设计理念 — Django 文档
设计理念
本文档解释了 Django 开发人员在创建框架时使用的一些基本理念。 它的目标是解释过去并引导未来。
总体
松耦合
Django 堆栈的一个基本目标是 松耦合和紧密内聚 。 除非绝对必要,否则框架的各个层不应该“了解”彼此。
例如,模板系统对Web 请求一无所知,数据库层对数据显示一无所知,视图系统不关心程序员使用哪种模板系统。
尽管为了方便 Django 带有一个完整的堆栈,但堆栈的各个部分尽可能独立于另一个堆栈。
更少的代码
Django 应用程序应该使用尽可能少的代码; 他们应该缺少样板。 Django 应该充分利用 Python 的动态功能,例如自省。
快速开发
21 世纪 Web 框架的重点是使 Web 开发的乏味方面变得更快。 Django 应该允许令人难以置信的快速 Web 开发。
不要重复自己(干)
每一个不同的概念和/或数据都应该存在于一个地方,而且只有一个地方。 冗余是不好的。 规范化是好的。
合理的框架应该从尽可能少的信息中推断出尽可能多的需求。
明确优于隐式
这是 PEP 20 中列出的 Python 核心原则,这意味着 Django 不应该做太多“魔术”。 除非有很好的理由,否则魔术不应该发生。 魔术只有在它创造了其他方式无法实现的巨大便利时才值得使用,并且它的实现方式不会使试图学习如何使用该功能的开发人员感到困惑。
一致性
该框架应在所有级别保持一致。 一致性适用于从低级(使用的 Python 编码风格)到高级(使用 Django 的“经验”)的所有内容。
模型
明确优于隐式
字段不应仅根据字段名称来承担某些行为。 这需要太多的系统知识并且容易出错。 相反,行为应该基于关键字参数,在某些情况下,还应该基于字段的类型。
包括所有相关领域逻辑
模型应该封装“对象”的每个方面,遵循 Martin Fowler 的 Active Record 设计模式。
这就是为什么模型表示的数据和关于它的信息(它的可读名称、默认排序等选项等)都在模型类中定义的原因; 理解给定模型所需的所有信息都应存储在 模型中 。
数据库API
数据库API的主要用处:
SQL效率
应该尽可能少地执行SQL语句,并且应该在内部优化语句。
这就是为什么开发人员需要显式调用 save()
,而不是框架在幕后默默地保存东西。
这也是为什么select_related()
QuerySet
方法存在的原因。 对于选择“每个相关对象”的常见情况,它是一个可选的性能增强器。
简洁, 强大的语法
数据库 API 应该允许使用尽可能少的语法进行丰富的、富有表现力的语句。 它不应依赖于导入其他模块或辅助对象。
当必要时, 在幕后插入应该是自动进行的.
每个对象都应该能够访问系统范围内的每个相关对象。 这种访问应该是双向的。
当有必要时, 可方便地选择使用原始 SQL 语句
数据库 API 应该意识到这是一条捷径,但不一定是万能的。 该框架应该可以轻松编写自定义 SQL——整个语句,或者只是自定义 WHERE
子句作为 API 调用的自定义参数。
URL 设计
松耦合
Django 应用程序中的 URL 不应与底层 Python 代码耦合。 将 URL 绑定到 Python 函数名称是一件糟糕而丑陋的事情。
按照这些思路,Django URL 系统应该允许同一应用程序的 URL 在不同的上下文中不同。 例如,一个站点可能将故事放在 /stories/
,而另一个站点可能使用 /news/
。
无限的灵活性
URL 应尽可能灵活。 任何可以想象的 URL 设计都应该被允许。
鼓励最佳实践
框架可以做到让开发者简单(或更加简单)地设计出漂亮的,而不是难看的 URL。
在 URL 中应避免出现文件后缀名。
在 URL 中使用 Vignette 式的逗号应该受到严厉的惩罚。
定义URL
从技术上讲,foo.com/bar
和 foo.com/bar/
是两个不同的 URL,搜索引擎机器人(和一些 Web 流量分析工具)会将它们视为单独的页面。 Django 应该努力“规范化” URL,这样搜索引擎机器人就不会被混淆。
这就是 :setting:`APPEND_SLASH` 设置背后的原因。
模板系统
逻辑分离的解决方案
我们将模板系统视为控制演示和演示相关逻辑的工具——仅此而已。 模板系统不应支持超出此基本目标的功能。
从 HTML 中解耦
模板系统不应设计为只输出 HTML。 它应该同样擅长生成其他基于文本的格式,或者只是纯文本。
XML不应被用于模板语言
使用 XML 引擎解析模板会在编辑模板时引入一个全新的人为错误世界 - 并在模板处理中产生令人无法接受的开销。
承担设计能力
模板系统的设计不应使模板必须在所见即所得的编辑器(如 Dreamweaver)中很好地显示。 这是一个太严重的限制,不允许语法像现在一样好。 Django 希望模板作者能够轻松地直接编辑 HTML。
更加直接的处理空格
模板系统不应该用空格做神奇的事情。 如果模板包含空格,系统应该像对待文本一样对待空格——只需显示它。 应显示不在模板标签中的任何空白。
不要发明一种编程语言
目标不是发明一种编程语言。 目标是提供足够的编程式功能,例如分支和循环,这对于做出与演示相关的决策至关重要。 Django 模板语言 (DTL) 旨在避免高级逻辑。
Django 模板系统认识到模板最常由 设计师 编写,而不是 程序员 ,因此不应假设 Python 知识。
安全与保障
开箱即用的模板系统应禁止包含恶意代码——例如删除数据库记录的命令。
这是模板系统不允许任意 Python 代码的另一个原因。
可扩展性
模板系统应该认识到, 高阶的模板作者可能想扩展它.
这是自定义的模板标签和过滤器背后的理念.
视图
简洁
编写视图应该像编写 Python 函数一样简单。 当一个函数可以执行时,开发人员不应该必须实例化一个类。
使用请求对象
视图应该有权访问请求对象——一个存储有关当前请求的元数据的对象。 该对象应该直接传递给视图函数,而不是视图函数必须从全局变量访问请求数据。 这使得通过传入“假”请求对象来测试视图变得轻巧、干净和容易。
松耦合
视图不应该关心开发人员使用哪个模板系统——甚至根本不关心是否使用了模板系统。
GET 方法和 POST 方法的区别
GET 和 POST 是不同的; 开发人员应该明确地使用其中之一。 该框架应该使区分 GET 和 POST 数据变得容易。
缓存框架
Django的缓存框架的核心目标是:
更少的代码
缓存应该尽可能快。 因此,围绕缓存后端的所有框架代码都应保持在绝对最小值,尤其是对于 get()
操作。
一致性
缓存 API 应该为不同的缓存后端提供一致的接口。
可扩展性
缓存 API 应该可以根据开发者的需求在应用层进行扩展(例如参见 [X109X] 缓存键转换)。