Django 设计模式与最佳实践
目錄
介绍
第一章 Django与模式
第二章 app的模式
第三章 模型
第四章 视图与URL
第五章 模板
第六章 admin接口
第七章 表单
第八章 处理旧版本代码
第九章 测试与调试
第十章 安全
第十一章 部署到生成环境之前的准备工作
附录
0
1
2
3
4
5
6
7
8
9
10
11
12
2
Django 设计模式与最佳实践
简介
所有译文同时以 GitHub Issue 的形式发布,点此阅读。
版权协议
除注明外,所有文章均采用 Creative Commons BY-NC-ND 3.0(自由转载-保持署名-非商用-
非衍生) 协议发布。
这意味着你可以在非商业的前提下免费转载,但同时你必须:
保持文章原文,不作修改。
明确署名,即至少注明 作者:cundi 字样以及文章的原始链接。
如需商业合作,请直接联系作者。
如果你认为译文对你所有帮助,而且希望看到更多,可以考虑小额捐助。
Django-Design-Patterns-and-Best-Practices
中文名:《Django 设计模式与最佳实践》
英文原版:https://www.packtpub.com/web-development/django-design-patterns-and-best-
practices
作者:Arun Ravindran
出版日期:March 2015
特色:Easily build maintainable websites with powerful and relevant Django design patterns
级别:Mastering
页数:Paperback 222 pages
第三章预览
第三章 模型
本章,我们会讨论以下话题:
模型的重要性
类图表
模型的结构模式
介绍
3
Django 设计模式与最佳实践
模型的行为模式
迁移
M大于V与C
在Django中,模型就是类,该类提供了一种处理数据库的面向对象方法。通常,每个类都引
用一个数据库表,每个属性都引用一个数据库列。你可以使用一个自动生成的API来查询这些
表。
模型是很多其他组件的基础。只要你有一个模型,你可以很快地得到模型admin,模型表单,
以及所有类型的通用视图。每种情况下,都需要你编写一两行代码,这样可以让它看上去没
有太多魔法。
模型也被用在更多的超出你期望的地方。这是因为Django可以以多种方式运行。Django的一
些切入点如下:
常见的web请求-响应流程
Django的交互式命令行
管理命令
测试脚本
异步任务队列,比如Celery
几乎所有的情况中,模型模块都需要导入(作为django.setup()的一部分)。因此,最好保证
模型远离任何不必要的依赖,或者导入任何的其他Django组件,比如视图。
简而言之,恰当地设计模型是件十分重要的事情。现在,让我们从SuperBook模型设计开
始。
介绍
4
Django 设计模式与最佳实践
注释
自带午餐便当
*作者注释:SuperBook项目的进度会以这样的一个盒子来表现。你可以跳过这个盒子,
但是在web应用项目中的情况下,你缺少的是领悟,经验 。
史蒂夫和客户的第一周——超级英雄情报监控(简称为S.H.I.M)。简单来说,这是一个
大杂烩。办公室是非常未来化的,但是不论做什么事情都需要上百个审核和签字。
作为Django开发者的领队,史蒂夫已经配置好了中型的运行超过两天的4台虚拟机。第二
天的一个早晨,机器自己不翼而飞了。一个附近的清洁机器人说,机器被法务部们给带
走了,他们要对未经审核的软件安装做出处理。
然而,CTO哈特给予史蒂夫了极大的帮助。他要求机器在一个小时之内完好无损地给还
回去。他还对SuperBook项目做出了提前审核以避免将来可能出现的任何阻碍。
那个下午的稍晚些时候,史蒂夫给他带了一个午餐便当。身着一件米色外套和浅蓝色牛
仔裤的哈特如约而至。尽管高出周围人许多,有着清爽面庞的他依旧那么帅气,那么平
易近人。他问史蒂夫如果他之前是否尝试过构建一个60年代的超级英雄数据库。
”嗯,对的,是哨兵项目么?“,史蒂夫说道。”是我设计的。数据库看上去被设计成了一
个条目-属性-值形式的模式,有些地方我考虑用反模式。可能,这些天他们有一些超级英
雄属性的小想法。哈特几乎等不到听完最后一句,他压低嗓门道:“没错。是我的错。另
外,他们只给了我两天来设计整个架构。他们这是在要我老命啊!”
听了这些,史蒂夫的嘴巴张的大大的,三明治也卡在了嘴里。哈特微笑着道:“当然了,
我还没有尽全力来做这件事。只要它成长为100万美元的单子,我们就可以多花点时间在
这该死的数据库上了。SuperBook用它就能分分钟完事的,小史你说呢?”
史蒂夫微微点头称是。他从来没有想过在这么样的地方将会有上百万的超级英雄出现。
模型搜寻
这是我们头一次见识到SuperBook中模型。我们只表示了基本模型,以及类图表中的表单的
基本关系,这也是早期尝试中所特有的情况:
介绍
5
Django 设计模式与最佳实践
让我们暂且忘掉模型,来谈谈我们正在构建的对象的术语。每个用户都有一个账户。用户可
以写多个回复或者多篇文章。Like同时关联到了一个独立用户/文章组合。
建议你为自己的模型画一个这样类图表。这一步的某些属性缺失了,不过你可以在之后对它
们进行详细补充。只要整个项目用图表表现出来,便可以轻松地分离app了。
下面是创建这个表现的一些提示:
盒子表示条目,它将成为模型。
名词通常作为条目的终止。
箭头是双向的,它代表了Django中的三种关系类型其中的一种:一对一,一对多(通过
外键实现),和多对多。
字段表明在模型中根据条目-关系模型(ER-modle)定义了一对多关系。换句来说,星
号就是声明外键的地方。
类图表可以映射到下面的Django代码中(分布于多个应用之中):
介绍
6
Django 设计模式与最佳实践
class Profile(models.Model):
user = models.OnToOneField(User)
class Post(models.Model):
posted_by = models.ForeignKey(User)
class Comment(models.Model):
commented_by = models.ForeignKey(User)
for_post = models.ForeignKey(Post)
class Like(models.Model):
liked_by = models.ForeignKey(User)
post = models.ForeignKey(Post)
后面,我们不会直接地引用User,而是使用更常见的settings.AUTH_USER_MODEL来。
把model.py分到多个文件中去
就像多数的Django组件那样,一个大的model.py文件可以在一个包内分割为多个文
件。package通过一个目录来实现,它包含多个文件,目录中的一个文件必须是一个称
为 __init__.py 特殊文件。
所有可以在包级别中暴露的定义都必须在 __init__.py 里使用全局变量域定义。例如,如果我
们分割model.py到独立的类,models子文件夹中的对应文件,比如,postable.py,post.py和
comment.py, 之后 __init__.py 包会像这样:
from postable import Postable
from post import Post
from commnet import Comment
现在你可以像之前那样导入models.Post了。
在 __init__.py 包中的任何其他代码都会在包运行时被导入。因此,它是一个任意级别包初始
化代码的理想之地。
结构模式
本节包含多个帮助你设计和构建模型的设计模式。
模式-规范化模型
问题:通过设计,模型实例的重复数据引起数据不一致。
解决方法:通过规范化,分解模型到更小的模型。使用这些模型之间的逻辑关系来连接他
们。
问题细节
介绍
7
Django 设计模式与最佳实践
想象一下,如果某人用下面的方法设计Post表(省略部分列):
超级英雄的名字
消息
Captain Temper
Professor English
Captain Temper
Capt. Temper
消息已经发布过了?
应该用“Is”而不是“Has"
消息已经发布过了?
消息已经发布过了?
发布时间
2012/07/07/07:15
2012/07/07/07:17
2012/07/07/07:18
2012/07/07/07:19
我希望你注意到了在最后一行的超级英雄名字和之前不一致(船长一如既往的缺乏耐心)。
如果我们看看第一列,我们也不确定哪一个拼写是正确的
—— Captain Temper或者Capt.Temper 。这就是我们要通过规范化消除的一种数据冗余。
详解
在我们看下完整的规范方案,让我们用Django模型的上下文来个关于数据库规范化的简要说
明。
规范化的三个步骤
规范化有助于你更有效地的存储数据库。只要模型完全地的规范化处理,他们就不会有冗余
的数据,每个模型应该只包含逻辑上关联到自身的数据。
这里给出一个简单的例子,如果我们规范化了Post表,我们就可以不模棱两可地引用发布消
息的超级英雄,然后我们需要用一个独立的表来隔离用户细节。默认,Django已经创建了用
户表。因此,你只需要在第一列中引用发布消息的用户的ID,一如下表所示:
用户ID
消息
12
8
12
12
消息已经发布过了?
应该用“Is”而不是“Has"
消息已经发布过了?
消息已经发布过了?
发布时间
2012/07/07/07:15
2012/07/07/07:17
2012/07/07/07:18
2012/07/07/07:19
现在,不仅仅相同用户发布三条消息的清楚在列,而且我们可以通过查询用户表找到用户的
正确的名字。
通常来说,你会按照模型的完全规规范化表来设计模型,也会因为性能原因而有选择性地非
规范化设计。在数据库中,Normal Forms是一组可以被应用于表,确保表被规范化的指南。
一般我们建立第一,第二,第三规范表,尽管他们可以递增至第五规范表。
介绍
8