美文网首页
django小技巧

django小技巧

作者: Nakamoto | 来源:发表于2018-06-29 16:35 被阅读0次
    1. 创建项目:django-admin.py startproject project_name
    • python manage.py help 查看所有命令集

    • 但是,系统对app有一个约定: 如果你使用了Django的数据库层(模型),你 必须创建一个django app。 模型必须存放在apps中

      • python manage.py startapp app_name
    • 用下面的命令对校验模型的有效性:python manage.py validate

    • sqlall 命令并没有在数据库中真正创建数据表,只是把SQL语句段打印出来: python manage.py sqlall books
      执行这些SQL语句,运行 syncdb 命令:python manage.py syncdb

      • syncdb 命令是同步你的模型到数据库的一个简单方法。它会根据 INSTALLED_APPS 里设置的app来检查数据库, 如果表不存在,它就会创建它。
      • 需要注意的是, syncdb 并 不能 同步模型的修改到数据库。如果你修改了模型,然后你想更新 数据库, syncdb是帮不了你的
      • 如果你再次运行 python manage.py syncdb ,什么也没发生,因为你没有添加新的模型或者 添加新的app
    • 只需要添加一个方法 __str__() 到 Publisher 对象。 __str__() 方法告诉Python要怎样把对象当作字符串来使用

    • __str()__ 也是一个很好的例子来演示我们怎么添加 行为 到模型里。 Django的模型不只是为对象定义了数据库表的结构,还定义了对象的行为。 __str__() 就是一个例子来演示模型知道怎么显示它们自己

    • Publisher.objects.all() 这行的每个部分:

    • objects 是干什么的?技术上,它是一个 管理器(manager) 。 管理器 将在附录B详细描述,在这里你只要知道它处理有关数据表的操作,特别是数据查找。

    • 所有的模型都自动拥有一个 objects 管理器;你可以在想要查找数据时是使用它。管理器的名称是可以自己更改的

    • 最后,还有 all() 方法。这是 objects 管理器返回所有记录的一个方法。 尽管这个对象 看起来象一个列表(list),它实际是一个 QuerySet 对象, 这个对象是数据库中一些记录的集合。附录C将详细描述QuerySet,现在,我们 就先当它是一 个仿真列表对象好了。

    • QuerySet 代表了你的数据库中的对象的一个集合。它根据所给参数可以构造若干个 过滤器 来缩小这个集合的规模。用SQL术语来讲,一个 QuerySet 就相当于一个 SELECT 语句,过滤器相当于诸如 WHERE 或者 LIMIT 的限定语。对一个模块来讲, Manager 是 QuerySets 的主要来源。它就像一个根本的 QuerySet ,可以对模块的数据库表中的所有对象进行描述。比如, Blog.objects 就是包含着数据库中所有的 Blog 对象的一个根本的 QuerySet 。

    • 每次都要用 order_by() 显得有点啰嗦。 大多数时间你通常只会对某些 字段进行排序。在这种情况下,Django让你可以指定模型的缺省排序方式:

      class Meta:
        ordering = ["name"]
      
    • 这个 ordering = ["name"] 告诉Django如果没有显示提供 order_by() , 就缺省按名称排序

    • Meta是什么?

      • Django使用内部类Meta存放用于附加描述该模型的元数据,查看附录B,在Meta项下面,获得更多选项信息
    • 你的模型的每个字段应该是一个适当的 Field 类的实例,Django使用这个字段类的类型去确定如下内容:

      • 数据库列类型(如 INTEGER 、 VARCHAR )。
      • 在Django的admin界面中使用的部件,如果你想要指定的话.(例如:<input type="text"><select>)
      • 用于Django的admin界面的基本的合法性验证。
    通用字段选项
    • 模型的Metadata选项:
      • db_table -- 模型对应的数据库表的名字
      • ordering -- 对象默认的排序方法,获取对象列表时会用到 ordering = ['-title']
      • permissions --创建对象时,需要额外加入权限表的权限
      • verbose_name -- 对象的友好可读名称(单数形式)
    管理器:
    • Manager 是提供给Django模型的数据库查询接口。Django程序的每个模型中至少存在一个 Manager
    • 管理器默认名称为 objects, people = models.Manager() 可通过定义修改
    URLconf 技巧
    • URLconf 中为某个特别的模式指定视图函数:你可以传入一个包含模块名和函数名的字符串,而不是函数对象本身
    • 应该使用带引号的 'mysite.views.current_datetime' 而不是 mysite.views.current_datetime当使用字符串技术时,你可以采用更简化的方式:提取出一个公共视图前缀。在我们的 URLconf 例子中,每一个视图字符串都是以 'mysite.views' 开始的,造成过多的输入。我们可以提取出公共前缀然后把它作为第一个参数传给 patterns()
        urlpatterns = patterns('mysite.views',
    
            (r'^now/$', 'current_datetime'),
    
            (r'^now/plus(\d{1,2})hours/$', 'hours_ahead'),
    
            (r'^now/minus(\d{1,2})hours/$', 'hours_behind'),
    
            (r'^now/in_chicago/$', 'now_in_chicago'),
    
            (r'^now/in_london/$', 'now_in_london'),
        )
    
    • urls.py 文件中 patterns()对象可以有很多个,需要叠加处理,如下示例:
        urlpatterns = patterns()
        urlpatterns += patterns()
      
    • url正则表达式中获取参数可以使用()
      (r'^articles/(\d{4})/$', views.year_archive)
    
    • 也可以使用命名正则表达式:命名的正则表达式组的语法是 (?P<name>pattern) ,这里 name 是组的名字,而 pattern 是匹配的某个模式
    (r'^articles/(?P<year>\d{4})/$', views.year_archive),
    
    • 理解匹配/分组算法:

      • 需要注意的是如果在URLconf中使用命名组,那么命名组和非命名组是不能同时存在于同一个URLconf的模式中的。如果你这样做,Django不会抛出任何错误,但你可能会发现你的URL并没有像你预想的那样匹配正确。
      • 具体地,以下是URLconf解释器有关正则表达式中命名组和非命名组所遵循的算法。
        1. 如果有任何命名的组,Django会忽略非命名组而直接使用命名组。
        • 否则,Django会把所有非命名组以位置参数的形式传递。
        • 在以上的两种情况,Django同时会以关键字参数的方式传递一些额外参数。更具体的信息可参考下一节。
    • 伪造捕捉到的URLconf值

    • 你可能会想增加这样一个URL, /mydata/birthday/ , 这个URL等价于 /mydata/jan/06/ 。这时你可以这样利用额外URLconf参数

      (r'^mydata/birthday/$', views.my_view, {'month': 'jan', 'day': '06'}),
    
    • 通过使用额外的URLconf参数,给视图函数传递额外参数

      # urls.py
      from django.conf.urls.defaults import *
      from mysite import models, views
      
      urlpatterns = patterns('',
          (r'^events/$', views.object_list, {'model': models.Event}),
          (r'^blog/entries/$', views.object_list, {'model': models.BlogEntry}),
      )
      
      # views.py
      from django.shortcuts import render_to_response
      
      def object_list(request, model):
          obj_list = model.objects.all()
          template_name = 'mysite/%s_list.html' % model.__name__.lower()
          return render_to_response(template_name, {'object_list': obj_list})
      
      
    • 我们通过 model 参数直接传递了模型类。额外URLconf参数的字典是可以传递任何类型的对象,而不仅仅只是字符串。

    • 这一行: model.objects.all() 是 鸭子界定 (原文:duck typing,是计算机科学中一种动态类型判断的概念)的一个例子:如果一只鸟走起来像鸭子,叫起来像鸭子,那我们就可以把它当作是鸭子了。需要注意的是代码并不知道 model 对象的类型是什么;它只要求 model 有一个 objects 属性,而这个属性有一个 all() 方法。

    • 了解捕捉值和额外参数之间的优先级

      (r'^mydata/(?P<id>\d+)/$', views.my_view, {'id': 3}),
    
    • 当冲突出现的时候,额外URLconf参数优先于捕捉值。也就是说,如果URLconf捕捉到的一个命名组变量和一个额外URLconf参数包含的变量同名时,额外URLconf参数的值会被使用。

    • 每个被捕获的参数将被作为纯Python字符串来发送,而不管正则表达式中的格式

    • 短路逻辑

    urlpatterns = patterns('',
        ...
        ('^auth/user/add/$', 'django.contrib.admin.views.auth.user_add_stage'),
        ('^([^/]+)/([^/]+)/add/$', 'django.contrib.admin.views.main.add_stage'),
        ...
    )
    
    • 在这种情况下,象 /auth/user/add/ 的请求将会被 user_add_stage 视图处理。尽管URL也匹配第二种模式,它会先匹配上面的模式。(这是短路逻辑)

    • 当一个请求进来时,Django试着将请求的URL作为一个普通Python字符串进行URLconf模式匹配(而不是作为一个Unicode字符串

    • 包含其他URLconf include()

        urlpatterns = patterns('',
            (r'^weblog/', include('mysite.blog.urls')),
            (r'^photos/', include('mysite.photos.urls')),
            (r'^about/$', 'mysite.views.about'),
        )
      
    • 指向 include() 的正则表达式并 不 包含一个 $ (字符串结尾匹配符),但是包含了一个斜杆。每当Django遇到 include() 时,它将截断匹配的URL,并把剩余的字符串发往包含的URLconf作进一步处理。

    • 被捕获的参数总是传递到被包含的URLconf中的每一行,不管那些行对应的视图是否需要这些参数

    • 额外的选项参数将总是被传递到被包含的URLconf中的每一行,不管那一行对应的视图是否确实作为有效参数接收这些选项


    深入模板引擎
    • 自定义过滤器
      from django import template
    
      register = template.Library()
    
      @register.filter(name='cut')
      def cut(value, arg):
          return value.replace(arg, '')
    
    • 自定义模板标签

      • 编写编译函数
        from django import template
      
        def do_current_time(parser, token):
          try:
              # split_contents() knows not to split quoted strings.
              tag_name, format_string = token.split_contents()
          except ValueError:
              msg = '%r tag requires a single argument' % token.contents[0]
              raise template.TemplateSyntaxError(msg)
          return CurrentTimeNode(format_string[1:-1])
      
      • 编写模板节点
        import datetime
        class CurrentTimeNode(template.Node):
          def __init__(self, format_string):
      
              self.format_string = format_string
          def render(self, context):
              now = datetime.datetime.now()
              return now.strftime(self.format_string)
      
      • 注册标签
        from django import template
        register = template.Library()
        register.tag('current_time', do_current_time)
      
      • 或者使用装饰器注册,方法同过滤器一样
    • 编写自定义模板加载器
      未完待续.....

    相关文章

      网友评论

          本文标题:django小技巧

          本文链接:https://www.haomeiwen.com/subject/sdbayftx.html