Django 1.6 Tips 拾遗

1. 在外键 related_name 直接创建关联对象

如果 Category 和 Item 是两个一对多的 model; 通过 Item.category 和 Category.item_set 调用; 那么: Category.item_set.create(…) 可以直接创建一个 Item 对象而无需指定其 category 属性! Accessing related objects

看上面的链接专题,确认以下事实: 这种 manager 叫做 RelatedManager,可以是 ForeignKey 的 另一端引用或者是 ManyToManyField 的两头的引用; .add(obj): 可以添加一个已经存在的对象到当前外键; .create(**kwargs): 可以直接创建一个对象对应到当前外键(外键字段缺省); .remove(obj1[,obj2,…]): 可以解除对指定对象的引用(只是 set null 不删除),但如果是 ForeignKey 的一对多引用,则必须要求 ForeignKey 的一端外键必须可空; .clear(): 等于 remove 所有的引用,也要注意同样的条件。

2. model manager 的 filter 多级搜索

例如:Item.filter(category__create_date__year=2014) 这样可以找到所有在 2014 年创建的分类下面的所有物件; 再例如:Item.filter(category__name__endswith=’材料’) 这个可以筛选出所有分类名称以 ‘材料’ 结尾的物件。 得好好研读一下 filter 的高级功能啊! Field lookups

3. 在 admin.ModelAdmin 对象可以设置分组显示

class PollAdmin(admin.ModelAdmin): fieldsets = [ (None, {’fields’: [’question’]}), (’Date information’, {’fields’: [’pub_date’], 'classes': ['collapse']}), ] 直接看这个,相比于用 field = (…) 来讲,可以分组显示各个字段,而不是一股脑放出来(这个以前没有留意,其实吧用处也不是很大)。

4. 在 admin.ModelAdmin 对象可以设置外键的多个嵌入编辑

class ChoiceInline(admin.StackedInline): model = Choice extra = 3

class PollAdmin(admin.ModelAdmin): #fields = ['pub_date', 'question'] fieldsets = ( (None, {'fields': ['question']}), ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), ) inlines = [ChoiceInline] 通过 admin.StackedInline 定义一个堆栈内联管理器; 然后通过 ModelAdmin 里面的 inlines 来指定用 inline 方式显示的字段,就可以在同一个页面中编辑更多的子对象。 除了 StackedInline 方式,还可以用 TabulatInline 的对象来派生,这个是用列表方式显示外键;

5. 在 admin.ModelAdmin 对象的 list_display 除了可以指定字段名还可以指定模型的方法

还可以在 model 层面用一些方法润饰这样的方法字段的行为: class Poll(models.Model): # ... def was_published_recently(self): return self.pub_date >= timezone.now() - datetime.timedelta(days=1) was_published_recently.admin_order_field = 'pub_date' was_published_recently.boolean = True was_published_recently.short_description = 'Published recently?'

6. template 目录是有优先级的,可以 hack contrib.admin 的 template

在默认情况下,django 会先找 TEMPLATE_DIRS 里面指定的模板路径,如果找不到,则会在对应的 APP 目录下面的 tempaltes 目录下面找模板。 因此,如果想 hack admin 界面的模板,可以在 django\contrib\admin\templates\ 下面找到相应的模板,然后按照目录结构复制到当前项目的 templates 文件夹下,然后进行修改,就可以 hack 到原生的 admin 界面了!

了解更多的 tempalte 查找顺序:template loader documentation

7. 命名 url 条目

urlpatterns 里面调用的 url() 函数可以指定一个 name 参数 from django.conf.urls import patterns, url from polls import views urlpatterns = patterns(’’, # ex: /polls/ url(r’^$’, views.index, name=’index’), # ex: /polls/5/ url(r’^(?P\d+)/$’, views.detail, name=’detail’), # ex: /polls/5/results/ url(r’^(?P\d+)/results/$’, views.results, name=’results’), # ex: /polls/5/vote/ url(r’^(?P\d+)/vote/$’, views.vote, name=’vote’), ) 像这样,习惯性去给 url 定义一个名称,后面可以在模板中使用动态的 url,或者灵活地通过视图反查动态的 url,这对 app 路径的解耦有相当重要的作用。 如果有多重可以匹配到的 template 找到,先匹配到的规则会生效,但是如果想手动指定一个 template 的位置,可以用到 template 的命名空间属性

8. 使用 get_object_or_404

使用这个方法来获取模型,相当于 try 一个 Model.objects.get,然后 except 一个 DoesNotExist,在里面 raise Http404 作用是如果获取不到,就会直接返回 404 的 response。 习惯是用这种方法,就可以在减少 model 和 view 的耦合的情况下去安全获取 model 对象,减少不少代码。

9. 在模板中使用 url 标签创建动态链接

可以再模板中使用 {% url [urlname] [*args] %} 来生成 url,其中 urlname 就是前面所说使用 url 函数时的命名参数 name 的值,然后后面跟着的是反向输入所有正则匹配的参数。 这样可以动态生成 Url,避免因为改变路由导致硬编码的链接失效(让动态链接自动跟路由设置看齐)。

10. URL 命名空间

前面说的是 url 的“命名”,其实还可以使用 url 的命名空间: 在 urls 的 include 函数,可以再加上一个 namespace 的命名参数来指定这个 urls 包的命名空间。 urlpatterns = patterns(’’, url(r’^polls/’, include(’polls.urls’, namespace="polls")), url(r’^admin/’, include(admin.site.urls)), ) 然后在 include 里面的模板,url 命名前面就加上了 polls: 这个命名空间了。 注意,一旦加入了命名空间,这个命名空间在 template 的 {% url %} 里面就不是缺省的了,如果不输入 polls: 在前面,就会抛出异常。

11. 在表单中加入 csrf_token

为了防止跨站脚本攻击,在 post 的 form 里面,要加入一个 {% csrf_token %} 标签,这相当于一个动态的 hidden field,作为一个动态的验证令牌,有这个字段后,django 内核会对 request 进行放行,否则会触发异常。

12. 习惯在 POST 处理之后返回 HttpResponseRedirect

在 post 处理之后,习惯性在 view 函数中总是返回一个 HttpResponseRedirect,以避免原来的 POST 状态被重复提交。 至于 HttpResponseRedirect 指定的 url,则尽量避免硬编码,使用 django.core.urlresolvers.reverse 函数来动态生成: 生成的原理跟原来的 template 嵌入 {% url %} 一样,可以通过 url 的命名来返回一个 url 字符串。 reverse([urlname], args, kwargs)

好了,这里已经写得很多,后面有个大块头需要编辑,关于通用视图,先结了这篇。

【转载请附】愿以此功德,回向 >>

原文链接:https://www.huangwenchao.com.cn/2014/03/django-review-tips.html【Django 1.6 Tips 拾遗】

发表评论

电子邮件地址不会被公开。 必填项已用*标注