[JQuery]一个简单的数字文本框

mikel阅读(928)

转载:http://www.cnblogs.com/Fenrir/archive/2008/12/04/1347981.html
前几天刚好需要用到就临时写了个,有需要的人可以用用看,可以校验输入的字符是否为合法字符,限制输入的字符为“0-9、-、.”,验证输入的值是否在规定范围内,出现违规的输入可以根据警告函数自动弹出错误提示,可限制小数位数,支持任意长度的数字。
 
属性:
MaxValue 设置最大值
MinValue 最小值
NumericDescription 该文本框的描述,用弹出错误提示时输出的信息。
TryParseImperfectThrowException 后台解析失败时是否抛出错误,为false时将使用默认值
DefaultValue 默认值
FractionLength 小数位最大位数
NumericValue 解析文本框得到的数字值
ClientWarning 客户端错误提示函数,如 alert
 
 
当格式发生错误的时候,如用复制黏贴的方式在文本框里输入字母后,当文本框失去焦点则会提示 XXXX 格式错误。XXXX取决于NumericDescription 属性;
 
当输入后的值超出范围时,会自动改变为允许的最大值或最小值。如果用复制黏贴的方式进行输入的当文本框失去焦点则会提示 XXXX 超出范围,必须大于 YYYY小于ZZZZ。XXXX取决于NumericDescription 属性 YYYY 取决于MaxValue ZZZZ取决于MinValue;
 
以上错误提示必须有设置ClientWarning 才会出现提示;
当TryParseImperfectThrowException为false时,如果错误的数据提交到后台不会抛出错误而会返回DefaultValue 的值
 
 
补充下说说设计思路吧,主要说说客户端的验证部分,服务端验证比较简单,因为服务端支持decimal型。
 
    由于JavaScript只支持int和float型的数字,超过就无法正确的转换,所以无法使用parseInt、parseFloat来将输入的文本转换为数字型来比较,所以使用字符串比较的方式来做。
 
    那么怎么使用字符串来比较任意位数的两个数字呢?应该将两个字符串填充为等长的字符串,比如2和100,如果直接进行比较则会变成2比较大,这样的结果显 然不是正确的,但如果把2填充为002就会得出正确的结果。如果是小数部分则往右边填充,比如:2.33和100,则应该填充为002.33和 100.00。这样的话可以正确的比较正数了,再来就是考虑比较正数与负数、或负数与负数的大小。
 
    当两个数字中第一个数为负数,比如-10和-100,如果再按之前的填充方式将会得到0-10和-100,这样显然是错的,所以一开始要将-号删掉,变成 10和100,并且记录下数字是否包含负号。当要填充字符串如上面的-10包含负号的时候进行右对齐并将负号加上变成-010。
 
     当两个数字中第二个数为负数,比如10和-100,照上面的想法删掉负号变成10和100,填充后变成010和100,这样是等长了 但加上负号后变成010和-100,这样数字又不等长了。所以当第二个数为负数而第一个数为正数的情况下必须为第一个数的左边多添加一个‘0’变成 0010和-100;
 
    这样就可以比较各种情况下数字的大小,而其他的一些功能都是小事了。

[Django]编写第一个Django app,第五部分——自定义管理员功能

mikel阅读(773)

转载:http://www.cnblogs.com/reallypride/archive/2008/12/02/1346215.html

自定义admin表单
这足以让我们惊讶好几分钟,所有的代码我们都不需要写。
当我们调用admin.site.register(Poll)时,Django只让你编辑这个对象并”推测“怎么把它显示在管理页面上。
很多时候,你可能想要控制admin的样式和功能。你可以在你注册对象的时候把选项告诉Django来实现。
让我们看一下在编辑表单中是怎样实现重新排序字段的。用下面的代码来替换admin.site.register(Poll):
  class PollAdmin(admin.ModelAdmin):
      fields = ['pub_date', 'question']

  admin.site.register(Poll, PollAdmin)
你将遵循这个模式——创建一个admin模型对象,然后把 它传递给admin.site.register()的第二个参数——任何时候你需要修改admin的选项都是修改一个对象。上面具体的改变 是"Publication date"字段在"Question"字段的前面:


只有两个字段并不会给人留下深刻的印象,但当admin表单包含有大量字段的时候,选择一个直观的排序方式就是一个重要的细节了。
并且,你可能想要把这些大量的表单字段分割归类为字段集:
  class PollAdmin(admin.ModelAdmin):
      fieldsets = [
          (None,               {'fields': ['question']}),
          ('Date information', {'fields': ['pub_date']}),
      ]

  admin.site.register(Poll, PollAdmin)
字段集中每个tuple的第一个元素是字段集的标题。现在我们的表单看起来像这样:


你可以给每个字段集指定任意的HTML样式。Django提供有一个"collapse"样式,它让每个具体的字段集在初始化时显示为折叠的。
当你的一个很长的表单中包含了许多不常用的字段时,这个样式就显得很实用了:
  class PollAdmin(admin.ModelAdmin):
      fieldsets = [
          (None,               {'fields': ['question']}),
          ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
      ]

 
添加关联的对象
OK,我们已经有了一个Poll admin页面。但是一个Poll有多个Choice,管理页面并没有显示Choices。
好的。
有两种方法可以解决这个问题。第一种方法是注册admin Choice,就像我们注册Poll那样。这很容易:
  from mysite.polls.models import Choice

  admin.site.register(Choice)
现在Django admin中的"Choices"已经可用了。这个"Add choice"看起来像这样:


在这表单中,"Poll"字段是一个选择框,包含数据库所有的poll。Django知道,外键在admin中代表一个<select>框。
在我们的例子中,只有poll存在外键。
还注意到"Poll"旁边的"Add Another"链接。每个包含有和其它对象构成外键关系的对象都会有这个链接。
当你单击"Add Another"时,你会得到一组带有"Add poll"表单的窗体。
如果你在窗体中添加一个poll并点击"Save",Django把这个poll保存到数据库中并把它作为选项动态添加到"Add choise"中。
但实际上,这是一种低效的添加Choice对象到系统中的做法。当你在创建Poll对象时,如果你能给它直接添加Choice就更好了。让我们实现它吧。
移去注册Choice模型的register()方法调用。然后,编辑Poll的注册代码:
  class ChoiceInline(admin.StackedInline):
      model = Choice
      extra = 3

  class PollAdmin(admin.ModelAdmin):
      fieldsets = [
          (None,               {'fields': ['question']}),
          ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
      ]
      inlines = [ChoiceInline]

  admin.site.register(Poll, PollAdmin)
这些代码告诉Django:"Choice对象在Poll的admin page中编辑。默认,为3个choice提供足够的字段。"
加载"Add poll"页面看看它是什么样子的:


它是这样工作的:有3个与Choice相关联的栏——在extra中指定的——每次你返回到一个已经创建的对象的"Change"页面时,你都会得到另外3个的额外栏。
但还是有个小问题。它占据了太多的空间来显示关联对象Choice的所有输入域。对于这个问题,Django提供一种制表的方式来显示关联的对象;
你只需要修改一下ChoiceInline的声明就行了:
  class ChoiceInline(admin.TabularInline):
      #…
使用TabularInline (取代StackedInline), 关联的对象显得更紧凑,它是基于表的格式:

自定义admin change list
现在Poll admin页面已经很好了,让我们对"change list"页面做些优化——它用于显示系统中所有的poll。
这是它看起来的样子:


默认,Django显示每个对象的str()。但有时候如果我们能显示个别字段的话会更有效果。
要做到这点,只需使用list_display admin选项,这是一个用于在对象的change list页面内把字段名作为列名显示的tuple:
  class PollAdmin(admin.ModelAdmin):
      # …
      list_display = ('question', 'pub_date')
  Just for good measure, let's also include the was_published_today custom method from Tutorial 1:

  class PollAdmin(admin.ModelAdmin):
      # …
      list_display = ('question', 'pub_date', 'was_published_today')
现在,poll change list页面看起来是这样:


你可以点击列头来排序这些值——除了was_published_today头外,因为排序不支持任何方法的输出值。
还注意到was_published_today列头默认是它的方法名(使用下划线替换空格)。但你可以通过给方法一个简短的属性描述来改变这个名:
  def was_published_today(self):
      return self.pub_date.date() == datetime.date.today()
  was_published_today.short_description = 'Published today?'
让我们对Poll change list页面添加另外的改进:过滤。添加下面的代码到PollAdmin中:
  list_filter = ['pub_date']
添加了一个"Filter"侧边栏让人们使用pub_date字段过滤change list:


这个过滤器显示的样式取决于你要过滤的字段的类型。
因为pub_date是DateTimeField,Django知道给DateTimeField一个默认的过滤器:

  "Any date","Today","Past 7 days","This month","This year"。
现在变得更好了。让我们添加一些检索功能:
  search_fields = ['question']
为change list添加了一个检索框。当有人输入检索值时,Django会检索question字段。
你可以使用多个检索字段——尽管它使用的是LIKE查询,既保证了自身的可读性,也保证了你的数据库的效率了。
最后,因为Poll对象包含有日期,如果能向下操作就更方便了。添加这行代码:
  date_hierarchy = 'pub_date'
它在change list页面添加了一个日期分层的导航。在上层,它显示所有可用的年份。然后向下显示月和日。
现在也是一个注意change lists给你提供了免费的分页功能的好时机。
默认是每页显示50条记录。Change-list的分页,检索,过滤,日期分层和列头排序都按照你想要的效果工作了。

[MVC].net企业级架构实战之7——Spring.net整合Asp.net mvc

mikel阅读(831)

转载:http://www.cnblogs.com/moye/archive/2008/11/30/1344369.html
.net企业级架构实战之7——Spring.net整合Asp.net mvc

既然提到mvc,就不得不说说微软在ASP.NET上的一个重要创造——postback机制。
但凡用ASP.NET做web开发的人,都和这个机制打过交道吧。ASP.NET页面aspx是其于这种自回发机制运转的。
我们平时用到的web控件,诸如TextBox、Button等,无一不是基于postback进行封装,在最终生成的html页中,它们还是会被转化成为<input type='text'>或者<input type='submit'>。
然后我们可以查看一下页面的源文件代码,会发现.net framework为我们写了不少东西:比如__doPostBack()这个js方法,用于提交窗体;WebForm_OnSubmit()方法会进行 窗体的验证;一个长长的__VIEWSTATE隐藏字段保存窗体上控件的状态信息等(令人发指)……等等。(详述请参见种玉堂的《再认识asp.net的postback机制:探索__doPostBack的来龙去脉 》)。
多么让人又爱又恨的发明! postback确实方便了开发者,尤其是小型应用,手到擒来;但性能呢?不敢恭维!尤其那一长串__VIEWSTATE,每每看到,都觉得揪心。

所以,在项目中的前端表现界面,决定启用mvc实现。
原来使用monoRail,感觉很好,但一直没有解决与Spring.net整合问题;而后来干脆听说,monoRail已经停止维护这个项目,只得作罢。幸好,此时还有一个选择——ASP.NET MVC
经过一段时间的尝试,终于把它与Spring.net整合在了一起,这意味着,mvc能共享到Spring.net中的所有对象,无缝集成。
由于ASP.NET MVCASP.NET 3.5 Extensions Preview 的一个部分,能不能在IIS6+Asp.net 2.0 framework下良好运行,也一度让人担忧,可喜的是,网上很多人都这么干,并且成功了。也就是说,如果决定在.net 2.0下使用asp.net mvc(本实例使用的版本为asp.net mvc Preview 4),除引用mvc的dll外(Microsoft.Web.Mvc.dll、System.Web.Mvc.dll等),还需额外的引用一个.net 3.5的dll(System.core.dll),此处提供这个包的下载:

Asp.net mvc preview 4 和 System.core.dll(v3.5):/Files/moye/Asp.Net_MVC_4.rar

简单说,.net mvc将视图(View)与控制器(Controller)进行了分离,表现与逻辑的关注点不再纠缠于一团。而Model的传递,微软提供了一套 DataDictionary(ViewDataDictionary、TempDataDictionary等)。同时,像monoRail一 样,.net mvc在页面中也可以其于模板书写表达式,比如:你可以在Controller中传递一个IList<T>过来,这边接收到对象拆箱后,循环 迭代输出一个行数等同的<Table>。
关于asp.net mvc的详尽原理,此处不累述,有兴趣可参阅 乱世重典的《Asp.net Mvc Framework 系列》。

欧克,回到重点,说说整合的事:

以上图示的结构:
将Controller单拿出来,做一个层,用以响应Web/Views中视图的请求。整合的目标就是:让这些Controller能够被注入,运行于Spring.net容器中。

通过学习Fredrik Normén的经验:《ASP.Net MVC Framework – Create your own IControllerFactory and use Spring.Net for DI 》,我们能知道,要创建自己的ControllerFactory,必须实现System.Web.Mvc的IControllerFactory接口。原型如(.net mvc Preview 4,版本不同接口也可能不一样):

using System;
using System.Web.Routing;
namespace System.Web.Mvc
{
    
public interface IControllerFactory
    {
        IController CreateController(RequestContext context, 
string controllerName);
        
void DisposeController(IController controller);
    }
}

在实现的CreateController方法中,将负责对不同的Views派发对应的Controller。这里做一个假设,/Views目录中有一个 叫User的目录,那框架就认为,这是一个User视图集合(具体表现在url上,如/User/home、/User/login等),应该有一个叫 UserController的控制器对此目录中的所有页面进行响应。

欧克,实践一把:

◆在Web的/Views创建一个web.config文件,并这样配置(它的作用:接管对.aspx页的请求流程):

web.config

◆在/Views中创建一个叫User的目录,并在其下添加一个Home.aspx页。当然这样是不能用的,需要修改一下页面和.cs: 

Home.aspx
Home.aspx.cs

◆此时,还需要一个Controller来负责响应User视图中的请求,如前结构图所示,在woodigg.controllers层中,创建一个UserController类,担当控制器角色:

UserControllers.cs

◆在控制器中,有一个Home方法,它刚好与Home.aspx同名,所以它就是负责响应Home页请求的方法。Home方法有一个整型的参数,说明这个请求也是传递参数的,形如http://localhost/User/Home/1(在.net 2.0 url没这么完美,它形如http://localhost/User.mvc/Home/1),那么1就是这个id参数,然后就去查数据库吧,1号用户的数据将它展示出来,当然这个示例没有取任何东西,只是传递了一个ViewData数据。
而我们也注意到,这里还进行了注入,欧克,开始整合Spring.net和.net mvc控制器工厂吧

◆做一个spring.net配置文件,controllers.xml,还放在web的/config目录中:

controllers.xml

◆然后,为实现IControllerFactory,在bll层中创建一个SpringControllerFactory类(一旦此bll程序集被引用,所有Views请求都将视这个实现类为Handler,控制器由它派发,这是.net mvc一个很妙的设计):

 

SpringControllerFactory.cs

◆这里需要说明的是ParameterFactory:一个静态参数工厂。它将当前站点的SERVER端物理目录存在static string类型的变量中,此处用到的三个变量CfgFilePath、CfgBusinessFilePath、 CfgControllersFilePath,分别为三个spring.net xml配置文件所在的物理路径。
显然,当Views/User/Home.aspx发出请求时,它会在/config/controllers.xml 中找到UserController控制器,并不算完——UserController请求注入UserMainDaoSpring对象,它又会在 /config/business.xml中找到这个对象的定义。完了吗?那得看UserMainDaoSpring是否也有注入别的对象了。
这种情况会乱吗?一点也不,即使你不用spring.net 整合它们,也一样会用到这些对象,只是使用的流程会有一些不同罢了。那么,在这个工厂中,只要捋清楚,你会用到哪些配置就行了(对这些配置xml文件,还 是按用途分类比较好,如页面一个,访问层一个,web services一个……然后,去管理它们!)。


 

[Django]编写第一个Django app,第四部分——初控Django的管理员功能

mikel阅读(847)

启用管理员功能
Django的管理员功能默认是不启用的——这是一个可选项。想要为你的程序启用管理员功能,需要做这三样事情:
  1.在INSTALLED_APPS设置中添加"django.contrib.admin"。

  2.运行python manage.py syncdb。当你添加一个新的应用程序到INSTALLED_APPS时,数据库的表需要手动更新。

  3.编辑文件mysite/urls.py,取消注释"Uncomment the next two lines…"下的那些行注释。这个文件是一个URL映射。

最后,你的urls.py文件应该像下面的那样:

from django.conf.urls.defaults import *
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Example:
    # (r'^mysite/', include('mysite.foo.urls')),

# Uncomment the admin/doc line below and add 'django.contrib.admindocs'
    # to INSTALLED_APPS to enable admin documentation:
    # (r'^admin/doc/', include('django.contrib.admindocs.urls')),

# Uncomment the next line to enable the admin:
    (r'^admin/(.*)', admin.site.root),
)

 

启动开发版服务器
让我们启动开发版服务器并浏览管理员页面。

  python manage.py runserver

现在,打开浏览器,在你的本地域中进入"/admin/"——如,htt://127.0.0.1:8000/admin/。你将会看到管理员的登录界面:

进入管理员页面

现在,尝试登录一下。(你在前面的教程中已经创建了超级用户帐号,还记得吗?)你将会看到管理员首页:

你会看到一些可编辑的内容,包括组,用户和站点。这些都是Django默认的核心特性。

使poll app在管理员站点中可修改

但我们的poll app在哪里呢?它没有在管理员站点首页出现。

只要做一点点的工作就行了:我们需要告诉admin,Poll对象有一个admin接口。

要做用这点,在你的polls文件夹中创建一个文件admin.py,然后把它编辑成这样:

Code

 

你需要重新启动开发版服务器才能看到你的变化。通常的,这个服务器会在你修改文件后自动重启,但新那一个文件并不会触发它的重启逻辑。

浏览免费的管理功能

现在,我们已经注册了Poll,Django知道了要把它显示在管理员站点的首页上:

单击"Polls"进入polls的"change list"页面。这个页面显示数据库中所有的polls,让我们选择其中一个然后修改它吧。

这里有一个我们在先前的教程中创建的"What's up?" poll:

单击"What's up?" poll然后编辑它:

注意这些东西:

  1.这个表单是根据Poll模型自动生成的。

  2.不现的模型域类型(DateTimeField, CharField)转换成适当的HTML input控件。每种域类型都知道怎样显示在Django的管理员站点中。

  3.每个DateTimeField都会获得一个免费的JavaScript图标。日期是"Today"和一个日历控件,时间是"now"和一个方便的包含有常用的时间值的弹出框。

页面下面的按钮是一些选项:

  1.Save——保存更改并返回列出这个对象类型被更改的部分的页面。

  2.Save and continue editing——保存更改并重新加载这些对象的管理员页面。

  3.Save and add another——保存更改并加载这个对象类型的新的空表单。

  4.Delete——显示一个删除确认页面。

通过单击"Today"和"Now"的快捷图标来更改"Date published"的值。单击"Save and continue editing",然后单击右上角的"History"。

你将看到一个页面,它列出了你通过Django管理功能所做的所有更改,包括时间和更改人的用户名:

[C#]Using ADO.NET Data Service - 服务端

mikel阅读(896)

转载:http://www.cnblogs.com/zlgcool/archive/2008/10/15/1312231.html

Using ADO.NET Data Service

 

ADO.NET Data Service是随同Visual Studio 2008 SP1提供的用于构建在数据对象模型 (EF-DEMX, LINQ-DBML) 之时来快速提供企业网内外的轻量级数据服务。ADO.NET Data Service Framework的目标是提供一个天生与web相结合的灵活的数据服务。它其中最醒目的特点就是通过URIs来指向以特定方式(JSON/ATOM)展现的数据(),并以REST方式来展现。所支持的URIs访问方式通过对标准HTTP verbsGET, POST, PUTDelete的支持来完成对数据的CRUD.

本文会通过一个具体的例子来演示如何使用ADO.NET Data Service以及其部分特性。

 

·         选择数据源

 

ADO.NET Data Service是由两部分组成的,一部分是其运行时,它提供了诸如Addressing(URI Translation), Open Format for Data Representation(公开的数据表现形式-JSON/ATOM), 数据传输协议等。另一部分就是数据访问部分,这部分是可以选择的,LINQ或者Entity Framework都是可以的,Data Service本身的功能就是将这些数据源暴露成一个面向web的数据服务。

 

创建一个服务分为两步:

·         ADO.NET Entity Framework来创建一个Entity Data Model – 这是为了以EDM来展现你的数据架构

·         建立数据服务

·         配置用户对数据访问的权限

如何创建一个EDM我们在这里不想多讲,下边的图和简单步骤会告诉你如何来创建一个EDM

1.       创建一个Web Application,这里我们命名为Allan.DataServiceDemo

2.       Solution Explore中右键点击选择添加新项,选择添加ADO.NET Entity Data Model,在Name中输入Northwind.edmx.       

      

3.       Entity Data Model Wizard中设置ConnectionString.点击下一步.

       

4.       在接下来的选择表、视图的窗体中选择你想要加入到EDM中的表。这里我们选择Employees, TerritoriesEmployeesTerrories表,然后点Finish. 到此我们的EDM已经完成了。接下来我们要做的事在EDM的基础上来构建Data Service.

 

·         创建数据服务

 

5.       右键点击项目并在弹出菜单中选择添加新项目。在弹出的对话框中选择 ADO.NET Data Service, 并将名称更名为NorthwindService.svc.通过这里你会发现,其实ADO.NET Data Service本质上是一个WCF.

 6.       Service本身已经建立,但现在还没有将数据暴露给客户端,并且没有相应的数据访问控制。当点击上一步中的Add按钮后,系统会打开NorthwindService.svc.cs文件,在这里我们需要做如下更改来暴露数据。

a.       将数据访问层类设立为被暴露的服务的数据源

b.      设定对相关数据实体集的权限和可访问性。

要做到这两点只需要更改一下所示的高两部分即可。第一个高两部分表示我们将NorthwindEntities作为我们的数据源。NorthwindEntities是我们刚才创建的EDMX的类名,Employees等表都已经作为其属性被Mapping成对象。第二个高亮部分是控制EntitySet(其实就是对应的表一级)的访问权限。例如你仍然可以通过下边的代码仅仅暴露Employees对象的只读权限:config.SetEntityAccessRule(“Employees”,EntitySetRights.AllRead.这样,服务只会暴露Employees集合并且只接受读取,而不能有更新操作。

public class NorthwindService : DataService<NorthwindEntities>

    {

        // This method is called only once to initialize service-wide policies.

        public static void InitializeService(IDataServiceConfiguration config)

        {

            // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.

            // Examples:

            config.SetEntitySetAccessRule("*", EntitySetRights.All);

            // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);

        }

    }

大功告成,你可以通过View In Browser来验证你的工作是否正确。

 

·        Addressing: Accessing Data Service via URIs

 

在前边提到过,Data Service通过URIs来指向a piece of data。也就是说我们通过URL就可以来做到访问数据,并且具有一定的数据过滤功能。抛弃高级的查询选项不说,基本的URL就可以来访问EntitySetEntity,以至于某个字段,字段的值等等。通过浏览你的Northwind.svc,我们可以看到以下数:

这里暴露了EmployeesTerritories两个数据集,这和我们之前设定的是相同的。通过以下的访问列表,你可以很容易的来在这个数据集合中导航,并获取你想要的数据。

Resource

URI

Service

http://localhost:4588/NorthwindService.svc/

Entity Set

http://localhost:4588/NorthwindService.svc/Employees

Entity

http://localhost:4588/NorthwindService.svc/Employees(1)

Relationship

http://localhost:4588/NorthwindService.svc/Employees(1)/Address

Property

http://localhost:4588/NorthwindService.svc/Employees(1)/Address/City

Property

http://localhost:4588/NorthwindService.svc/Employees(1)/FirstName

ADO.NET Data Service同样提供了以下的查询选项:

Option

Description

Example

expand

类似于LINQ中的LoadOptions,以此来指定加载此对象相关的通过expand指定的对象。如果需要加载多个对象,用逗号分隔。

http://localhost:4588/NorthwindService.svc/Employees(1)?$expand=Territories

同事加载当前employee对应的Territories.

orderby

指定排序方式。语法为:$orderby=Field [ASC|DESC], [Field[ASC|DESC]]

http://localhost:4588/NorthwindService.svc/Employees?$orderby=FirstName

Skip

Top

类似于LINQ中的Skip(PageSize * PageIndex).Take(PageSize)用来实现分页。表示越过多少条记录,取接下来开始的几条记录。也可分开始使用两个选项。

http://localhost:4588/NorthwindService.svc/Employees?$orderby=FirstName&$skip=3&$top=3

http://localhost:4588/NorthwindService.svc/Employees? $skip=3  

Filter

通过filter这个参数可以在URL里传递过滤条件。

http://localhost:4588/NorthwindService.svc/Employees?$orderby=FirstName&filter=substringof(FirstName,'A')

对于如上边所示的查询表达式,ADO.NET Data Service提供了一些函数和标记来帮助我们组建适合的查询表达式(Query Expression).下表总结了常见的组建Query Expression的标记、函数等,以供查询和参阅。

1.       Logical Operators – 逻辑运算符

Operator

Description

Operator

Description

eq

Equal

ne

Not Equal

gt

Greater than

ge

Greater than or equal

lt

Less than

le

Less than or equal

and

Logical and

or

Logical or

not

Logical negation

()

Precedence grouping

 

2.       Arithmetic Operators – 算数运算符

Operator

Description

Example

add

Addition

/Product?filter=UnitPrice add 5 gt 10

sub

Subtraction

/Product?filter=UnitPrice sub 5 gt 10

mul

Multiplication

/Orders?$filter=Freight mul 800 gt 2000

div

Division

/Orders?$filter=Freight div 10 eq 4

mod

Modulo

/Orders?$filter=Freight mod 10 eq 0

3.       Functions – 函数

String Functions

bool substringof(string p0, string p1)

bool endswith(string p0, string p1)

bool startswith(string p0, string p1)

int length(string p0)

int indexof(string arg)

string insert(string p0,int pos, string p1)

string remove(string p0, int pos)

string remove(string p0, int pos, int length)

string remove(string p0, string find, string replace)

string substring(string p0, int pos)

string substring(string p0, int pos, int length)

string tolower(string p0)

string toupper(string p0)

string trim(string p0)

string concat(string p0, string p1)

 

Date Functions

int day(DateTime)

int hour(DateTime)

int minute(DateTime)

int month(DateTime)

int second(DateTime)

int year(DateTime)

Math Functions

double round(double)

decimal round(decimal)

double floor(double)

decimal floor(decimal)

double ceiling(double)

decimal ceiling(decimal)

       

通过这些看似简单的函数和逻辑/算数操作符,可以在很大程度上通过URL来做一些简单的查询和过滤。通过分析查询结果你会清楚的看到:

·         当有多个对象被返回是,在atom模式下,数据以feed的方式返回。

·         每个entry包含一个对象。

·         每个entry会提供link标签来给出自己的URL和其关联对象的URL

·         属性会被包含在Content内部以application/xml表示

·         每个属性都是content内一个子节点。

·         所有的数据和关系均以纯XML表现

·         默认情况下关联对象不被加载(expand可以加载)

  

·        Query Interceptors – 查询拦截

查询拦截非常有用,它起个代理或者把关的作用。当你仅仅想把具有某种状态或者特征的数据返回给客户端时,用拦截查询就可以实现。比如,数据库中的Employee信息,对于已经离开公司的员工我们会将其状态设置为Leave,而在我们不打算将这些信息流露出去时,写一个Query Interceptor仅仅返回状态<>Leave的记录,那么所有客户端请求与Employee有关的数据时将被强制只能得到状态不为Leave的记录。换句话说,Query Interceptor的代理函数返回的数据在表面上替换了Employees的记录。

下边的示例限定了客户端仅能得到国家是USAEmployees信息:

[QueryInterceptor("Employees")]

public Expression<Func<Employees, bool>> ReturnUSAEmployees()

{

    return e => e.Country == "USA";

}

Query Interceptors是面向EntitySet(也就是Table)的,通过修改QueryInterceptorAttribute的参数,你可以给任何一个EntitySet来创建一个查询拦截器。看看我们刚才设置的查询拦截器是否工作呢?

 

没错,仅仅返回了5Country=USA的记录。Nice!

·        Change Interceptors – 数据更新拦截

看起来,Change InterceptorsQuery Interceptors很相似,都是用来拦截客户端操作的。不同的是,前一个word,一个是面向query的,一个是面向change的。顾名思义,Change Interceptors面向的就是提交到服务器的的数据更新操作:包括Add, Change Delete,分别对应在数据添加操作,数据更改操作和数据删除操作这些是由UpdateOperations参数来提供的。下边的示例实现了在执行添加操作时,如果Employee实例的Country属性为空,则默认设置为USA:

[ChangeInterceptor("Employees")]

public void AssignDefaultCountry(Employees c, UpdateOperations operation)

{

    if (operation == UpdateOperations.Add)

    {

        if (c.Country.Trim().Length == 0)

        {

            c.Country = "USA";

        }

    }

}

不要忘记给这个方法加入ChangeInterceptor属性。而对于所拦截的操作对象,同样是通过更改ChangeInterceptorAttribute的参数来实现的。

·        扩展ADO.NET Data Service

ADO.NET Data Service 为我们提供了快速构建一个数据服务的平台,但到目前为止,除了数据库中的对象(还不包括存储过程),我们仍然无法加入自己的方法,这显得好像很不灵活。当然,ADO.NET Data Service还是为我们提供了这样的一种方式来扩展已有的整套生成好的数据服务的。你可以添加一些你自己的方法,例如操作存储过程,自己的逻辑,返回特殊处理后的数据这样的方法,然后通过添加WebGetAttribute来使其变成一个ServiceOperation来暴露给客户。

[WebGet]

public IQueryable<Employees> GetEmployeesByCountry(string country)

{

    var employees = from c in this.CurrentDataSource.Employees

                                 where c.Country == country

                                 select c;

 

    return employees;

}

 

同时还要设置这个方法的权限(InitializeService方法中)

config.SetServiceOperationAccessRule("GetEmployeesByCountry", ServiceOperationRights.All);

 

如何去访问这个方法呢?因为你无法再meta中(实际上就是http://localhost:4588/NorthwindService.svc)找到对这个方法的描述。很简单,直接试验一下下边的URL是否工作呢?

http://localhost:4588/NorthwindService.svc/GetEmployeesByCountry?Country='USA'

 

服务端的设置好像该有的都有了哦?除了Data Service的表现方式:Atom还是JSON,这个另行解决吧,起码得有传输的数据包来展现。另外的有关客户端消费的(服务端消费和客户端AJAX消费)我们在下一个话题中来介绍吧🙂 

 

点击链接下载练习代码: http://files.cnblogs.com/zlgcool/Allan.DataServiceDemo.rar

[Django]编写第一个Django app,第三部分——玩转模型层的API

mikel阅读(776)

玩转模型层的API

现在,让我们进入Python shell中玩转Django为我们提供了的免费的API。使用下面的命令运行Python shell:

  python manage.py shell

现在你已经进入到shell中了,研究一下这些数据库的API吧:

Code

 

等下。<Poll: Poll object> 根本就不能帮助我们描述这个对象。让我们编辑polls模型来修正它(在polls/models.py文件中),给Poll和Choice方法各添加一个__unicode__()方法。

class Poll(models.Model):
# 
    def __unicode__(self):
return self.question
class Choice(models.Model):
# 
    def __unicode__(self):
return self.choice

 

如果__unicode__()看起来没有执行

如果你给你的models添加的__unicode__()方法并没有看到它们的描述信息有变化,你很可能正在使用的是旧版本的Django。(本教程是面向Django最新的开发版写的。)旧版使用__str__()方法。

给你的models添加__unicode__()方法是件很重要的事情,它不仅仅是为了使你在提示窗口中得到智能的提示,更是因为对象的描述在Django自动生成的admin中会使用到。

为什么是__unicode__()而不是django.db.models.Model.__str__()?

如 果你熟悉Python的话,你可能习惯于给你的类添加django.db.models.Model.__str__()方法而不是 __unicode__()方法。我们这里之所以使用__unicode__()是因为Django models默认是处理Unicode的。所有保存在你的数据库中的数据在返回的时候都转换为Unicode。

Django models有一个默认的方法django.db.models.Model.__str__(),它会调用__unicode__()方法并返回一个 UTF-8格式的字符串。也就是说,unicode(p)将会返回一个Unicode的字符串,而str(p)将会返回一个普通的字符串,它的字符是被编 码为UTF-8的。

如果你还不理解的话,你只要记得给你的models添加__unicode__()方法就行了。如果运气不背的话,事情就会如你所愿的执行。

注意下面这些普通的Python方法。让我们添加一些自定义的方法,就如例子所演示的:

 

import datetime
# 
class Poll(models.Model):
# 
    def was_published_today(self):
return self.pub_date.date() == datetime.date.today()

 

注意到,我添加了import datetime来引用Python的标准datetime模块。

让我们再次运行python manage.py shell来进入Python shell吧:

 

Code

 

如果还有读者还不熟悉Python和Django的安装,请阅读我写的一篇关于这方面的教程:

[Django]编写第一个Django app,第二部分——创建模型和使用模型

mikel阅读(706)

转载:http://www.cnblogs.com/reallypride/archive/2008/11/29/1343615.html

创建模型

现在你的运行环境——"project"——已经建好了,现在准备让它开始工作了。

你在Django中写的每一个应用程序都是由Python包组成,它们都在Python的路径下,遵循一定的约定。

Django自带有一个实用的工具,自动生成app的基本目录结构,因些,你可以把更多的精力放在代码的编写上而不是创建目录上。

Projects vs. apps(项目与应用程序)

project和app之间有什么不同之处呢?一个app是实现某种功能的Web 应用程序——例如,一个网络博客系统,一个公共记录的数据库或一个简单的投票程序。一个project是具体网站app和配置的集合。一个project 可以包含多个apps。一个app可以在多个project中。

在本教程中,我们将会在mysite文件夹中简单地创建我们的poll app。因而,这个app属于这个project——mysite,在poll app中的python代码相当于mysite.polls。在本程序后面,我们会讨论发布您的apps时的解耦。

要创建你的app,先要确保你是在mysite文件夹中,然后输入这些命令:

  python manage.py startapp polls

它们将会创建一个polls文件夹,里面的内容是:

  polls/

    __init__.py

    models.py

    views.py

这个目录结构就是app应用程序。

编写数据库Web应用程序的第一步是定义你的模型层——基本上就是你的数据库的布局,但添加了些额外的元数据。

在我们的简单的poll app中,我们将会创建两个模型:polls和choices。poll包含question和publication date。choise有两个字段:选择的文字和投票记分。每个choise都和一个poll关联。

这些概念可以用简单的Python类来描述。把文件polls/models.py编辑成如下面的样子:

  from django.db import models

  class Poll(models.Model):
      question = models.CharField(max_length=200)
      pub_date = models.DateTimeField('date published')

  class Choice(models.Model):
      poll = models.ForeignKey(Poll)
      choice = models.CharField(max_length=200)
      votes = models.IntegerField()

关于max_length的错误

如果Django给你一个错误信息提示max_length不是正确的参数,你很可能使用的是旧版的Django。(本教程是针对Django最新的开发版本写的)(顺便说一下,旧版使用的参数是maxlength)。

这些代码都比较简单直观。每个模型都对应一个类,它是django.db.models.Model的子类。每个模型都包含有一些类级变量,它们代表数据库的字段。

每个字段都是Field类的实例——如,CharField是character字段,DateTimeField是日期字段。这些变量告诉Django字段保存的数据类型。

Field实例名(如question或pub_date)是字段的名字,使用机器友好的格式。你可以在Python代码中使用它们,也可以在数据库中作为列名使用。

你可以使用第一个可选的参数来定义Field的人性化的名字。它在Django中作为提示的内容。如果这个字段没有提供,Django将使用对机器 易读的名字。在这个例子中,我们只为Poll.pub_date定义了人性化的名字。模型中的其它字段都是使用对机器易读,对人不易阅读的名字。

一些Field类需要参数。例如CharField,需要你给出max_length。它不仅是用于数据库的架构信息中,还用于数据验证,等会我们就会看到了。

最后,关注一下关联的定义,使用ForeignKey。它告诉Django每个Choice和一个Poll关联。Django提供有所有常用的数据库关联:多对一,多对多,一对一。

使用模型

这些少量的模型代码给了Django大量的信息。通过它,Django能够做这些事情:

  1.为这个app创建数据库的架构信息(Create TABLE 声明)。

  2.创建Python的数据库访问API来获取Poll和Choice对象。

但首先,我们要告诉我们的project,polls app已经安装好了。

再次编辑settings.py文件,修改INSTALLED_APPS的设置,加入字符吕'mysite.polls'。这样,它的代码看起来如下:

  INSTALLED_APPS = (
      'django.contrib.auth',
      'django.contrib.contenttypes',
      'django.contrib.sessions',
      'django.contrib.sites',
      'mysite.polls'
  )

现在,Django已经知道了mysite中包含有polls app。让我们运行另一个命令:

  python manage.py SQL polls

你应该会看到一些类似于下面的信息(polls app的Create TABLE SQL描述语句)

BEGIN;
Create TABLE "polls_poll" (
    "id" serial NOT NULL PRIMARY KEY,
    "question" varchar(200) NOT NULL,
    "pub_date" timestamp with time zone NOT NULL
);
Create TABLE "polls_choice" (
    "id" serial NOT NULL PRIMARY KEY,
    "poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"),
    "choice" varchar(200) NOT NULL,
    "votes" integer NOT NULL
);
COMMIT;

注意以下各项:

  1.这些输出依赖于你所使用的数据库。

  2.表名是自动生成的,由app(polls)名和模型名的小写组成——poll和choice。(你可以重写这个行为)

  3.主键(IDs)是自动添加的。(这个你也可以重写)

  4.为了方便,Django在外键字段名后面加上"_id"。你也可以重写这个。

  5.外键关系使用显式的REFERENCES声明。

  6.它根据你使用的数据库做不同的调整,因些一些特殊的字段类型,如auto_increment(MySQL),serial(PostgreSQL),或integer primary key(SQLite)

     都会为你自动处理。相同地,对于引号也是如此。——如,使用单引号或双引号。本教程的作者使用的是PostgreSQL,因此例子中输出的是使用

   PostgreSQL的语法。

  7.这些sql命令并不是运行在数据库的实际的SQL,它只是打印在屏幕上,因些你能看到Django认为需要使用什么SQL语句。如果你愿意,你可以copy

     并粘贴这些SQL到你的数据库提示框中。然而,很快你就会看到,Django提供了更简单的方法来向数据库执行这些SQL语句。

如果你有兴趣,你还可以运行下面的命令:

  1.python manage.py validate —— 检查模型的结构上是否有错误。

  2.python manage.py sqlcustom polls —— 输出所有在应用程序中定义的自定义SQL描述(如表的限制或约束)。

  3.python manage.py sqlclear polls —— 输出在这个app中删除已存在的表的Drop TABLE描述。

  4.python manage.py sqlall polls —— 一个组合所有的sql,sqlcustom和sqlindexes的SQL命令.

从这些输出的命令中能帮助我们了解在自动生成引擎下实际做了些什么事情。

现在,再次运行syncdb在你的数据库中创建这些模型的表。

  python manage.py syncdb

syncdb命令在你的数据库中运行从'sqlall'中得来的sql命令,它只运行在INSATLLED_APPS中,还没有保存存在你的数据库中的apps。

它创建所有的表,初始化数据和索引你最后一次运行syncdb时你已经添加到你的工程中的apps。syncdb你想运行多少次都可以,

它只创建还没有存在的表。

 

因为第一次翻译英文资料,计算机术语了解得不多,英语水平也不行,翻译得不够准确的地方还请多多包涵。

[Django]编写第一个Django app,第一部分——创建项目

mikel阅读(885)

转载:http://www.cnblogs.com/reallypride/archive/2008/11/28/1343356.html

编写第一个Django app,第一部分——创建项目

让我们通过例子来学习。

通过这个指导教程,我们将一步步地教你创建一个简单的投票系统。
这个系统分为两部分:
1.一个公共的页面让人们投票和查看投票结果。
2.一个管理员页面让你添加,修改和删除投票。

我们假定你已经安装了Django。你可以运行Python编译器并输入import django
来测试Django是否已经安装。如果命令运行成功,没有错误,说明Django已经安装了。

新建项目

如果你是第一次使用Django,你必须确保一些初始化已经完成。也就是,你需要自动生成
一些代码来创建Django项目——一系列的Django设置实例,包括数据库配置,Django特定
的选项和程序特定的设置。

使用命令行,cd进入你要保存你的代码的文件夹,运行命令django-admin.py startproject mysite。
它会在当前文件夹里创建一个mysite文件夹。

如果你是通过python setup.py安装Django的话,django-admin.py将会在你的系统路径下。
如果不在你的路径下,你可以在site-packages/django/bin中找到它,site-packages是你的Python的
安装目录。
(对于上面这段话我不是很理解,我是把django-admin.py拷贝到存放代码的文件夹下,然后运行命令
django-admin.py startproject mysite来创建项目的)。

让我们看一下startproject生成了些什么:
mysite/
 __init__.py
 manage.py
 settings.py
 urls.py
这些文件是:
1.__init__.py:一个空文件,它用来告诉Python把这个文件夹看成是一个Python包。(如果你是一个初学者,
  阅读Python的官方文档来了解更多的关于包的内容。)
2.manage.py:一个实用的命令行,它让我们通过各种各样的途径和Django项目进行交互。
3.settings.py:设置/配置Django项目
4.urls.py:Django项目的URL映射。

开发版服务器

让我们确认这些工作。切换到mysite文件夹,运行命令python manage.py runserver。你将会看到命令行
输出下面的信息。
Validating models…
0 errors found.

Django version 1.0, using settings 'mysite.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

你已经启动了Django的开发版服务器,一个用纯Python写的轻量级Web服务器。我们已经把它包含在Djangok ,
所以你能快速地开发项目而不用配置产品服务——例如Apache——直到你将要发布产品。

现在这是一个好的时机来注意:不要使用这个服务器作为产品的运行环境。它仅仅是在开发的时候使用。
(我们的业务是开发Web框架而不是Web服务器。)
现在这个服务器已经运行,使用你的浏览器浏览http://127.0.0.1:8000/
你将会看到一个"Welcome to Django"的亮蓝色粉蜡笔的页面。它已经工作了。

改变它的端口
默认情况下,runserver命令在8000端口启动开发版服务器。如果你想改变服务器的端口,把端口号作为
命令行参数传入。例如,这条命令在8080端口中启动服务器:
python manage.py runserver 8080

(在我的电脑上,使用python manage.py runserver启动服务器会报错,把命令前面的python去掉
就能正常运行了,不知道是怎么回事。)

准备数据库

现在,编辑settings.py。它是一个包含有与Django设置相对应的模块级变量的常规的Python模块。
修改这些设置以匹配你的数据库连接参数:
1.DATABASE_ENGINE—— 'postgreSQL_psycopg2', 'mySQL' or 'SQLite3'中的一个,
  其它的也适用。
2.DATABASE_NAME——数据库的名字。如果你使用的是SQLite,数据库是你电脑上的一个文件;因些,
  DATABASE_NAME就是文件完整的绝对路径,包含文件名。如果文件不存在,它会在你第一次使用数据库
  的时候创建。
  当指定文件的路径时,要使用斜线,即使是在windows下(如C:/homes/user/mysite/sqlite3.db)。
3.DATABASE_USER——你的数据库的用户名(SQLite不使用)。
4.DATABASE_PASSWORD——你的数据库的密码(SQLite不使用)。
5.DATABASE_HOST——数据库所在的主机。如果你的数据库在相同的物理机器上,保留它为空字符串(SQLite不使用)。

如果你是个数据库新手,我们建议你使用简单的SQLite(把DATABASE_ENGINE设置为'sqlite3')。
SQLite是Python2.5和更新的版本的一部分,因此你不需要安装任何东西。
如果你使用的是PostgreSQL或者MySQL,要确保你已经创建了数据库。要创建数据库可以在数据库的交互对话框中
使用命令"Create DATABASE database_name;" 。
如果你使用的是SQLite,你不需要预先创建任何东西——数据库会在需要它的时候自动创建。

当你编辑settings.py的时候 ,注意下面的INSTALLED_APPS的设置。片个变量保存所有已经激活的Django应用
程序的Django实例的名字。Apps能在多个项目中使用,你可以打包和发布它们,让它们在其它项目中使用。

默认情况下,INSTALLED_APPS包含有下面的apps,它们都是来自于Django:
1.django.contrib.auth — 用户验证系统。
2.django.contrib.contenttypes — 内容类型框架。
3.django.contrib.sessions — session框架。
4.django.contrib.sites — 使用一个Django管理多个站点的框架。
这些应用程序默认是包含的,方便通常情况下的使用。

每个应用程序都需要使用和至少一个数据表,因些我们在使用它们之前要先创建数据表。0
要做这些事情,使用下面的命令即可:
python manage.py syncdb

syncdb命令在你的settings.py文件中查找NSTALLED_APPS的设置并使用数据库的设置创建所需要的数据表。
你将会看到每个数据表的创建信息,并且如果你为验证系统创建超级用户帐号的话,你将会看到一个对话框。
继续,并完成它。

如果你感兴趣,运行你的数据库客户端命令行,输入\dt (PostgreSQL), SHOW TABLES; (MySQL),
或者 .schema (SQLite)来显示Django创建的表。

就如上面所说的那样,默认应用程序包含这些是为了一般情况下的需求,但并不是每个人都需要使用它们。
如果你不需要它们,你可以把它们从INSTALLED_APPS中注释掉或者删除掉,不过这要在你运行syncdb命令之前。
syncdb命令只创建在INSTALLED_APPS中的apps的表。

[Delphi]Delphi Prism

mikel阅读(971)

  很多年来Delphi都是Windows平台上强有力的竞争者。它将VB的快速应用开发和更加强大的语言结合起来。然而当.NET横空出世 后,Delphi逐渐丧失了其霸主地位。Delphi的Win32编译器已经被人所淡忘,同时Borland也将精力转向了.NET开发。Delphi 8不再支持Win32开发,同时其.NET版本也与之前的程序不兼容。由于这个原因,再加上稳定性的问题,最终导致大多数开发者放弃了Delphi 8和9。

由于最近Embarcadero Technologies收购了Borland的开发部门,这令Delphi获得了新生。其核心产品Delphi 2009又重新开始关注Win32开发了。同时,微软最近在协议上的变化又给了新版本的Delphi一个出路。

去年,我们曾报道过微软准备向独立的系统供应商免费提供Visual Studio。这个名为Visual Studio Shell的版本可用作任何开发套件的基础。Embarcadero正在用其开发Delphi Prism。

Delphi Prism给Embarcadero带来了一些Borland未曾拥有的东西。通过将Visual Studio Shell作为起始点,他们可以立刻与微软的专业开发工具展开竞争而无需弥补迷失的那几年光阴。

凭借Delphi Prism,Embarcadero可以专注于微软比较欠缺的领域:跨平台开发。通过使用Visual Studio和Delphi Prism,开发者编写的程序可以运行在非微软的操作系统上。

敞开说吧,Delphi Prism提供了Gtk#的项目模板、OS X上的WinForms、面向OS X/Tiger的Cocoa以及面向OS X/Leopard的Cocoa。Tim Anderson补充到:

我推荐在Mac上的VM运行Visual Studio,因为Windows无法运行Cocoa应用。同时你需要使用Apple的Interface Builder,因为在Visual Studio中并没有GUI设计器。

这并不是第一次提出将Delphi作为一个跨平台的开发工具了。有一个名为Kylix的项目,它支持Linux操作系统。但它的价格太高,同时其稳定性还很让人质疑,更不用说与Delphi源代码的不兼容性了,因此它很快就失败了。