本文档解释了 Django 开发人员在开发 Django 时使用的一些基本哲学, 它的目标是解释过去并指导未来
Django 栈的基本目标是 低耦合高内聚。框架里的不同层(Layers)不应该知道对方的代码,除非它们确实需要。
For example, the template system knows nothing about web requests, the database layer knows nothing about data display and the view system doesn't care which template system a programmer uses.
尽管为了方便 Django 带有一个完整的堆栈,但堆栈的各个部分尽可能独立于另一个堆栈。
Django 应用的代码应该尽可能地精简,Django 应该充分利用 Python 的动态能力,比如自省机制(introspection)。
The point of a web framework in the 21st century is to make the tedious aspects of web development fast. Django should allow for incredibly quick web development.
这是在 PEP 20 列出的核心 Python 原则,这意味着 Django 不应该使用太多的“魔术”。除非有一个很好的理由,否则不应该出现魔术。只有当魔术创造了巨大的便利,并且使用其他方式难以实现时,它才值得使用,而且它的实现方式并不会让试图学习如何使用该功能的开发人员感到困惑。
框架应在所有层级上保持一致。一致性适用于从低级(Python 的编码风格)到高级(使用 Django 的“经验”)的所有内容。
字段不应该仅仅根据字段的名称来假定某些行为。这需要对系统有太多了解,并且容易出现错误。相反,其行为应该基于关键字参数,并且在某些情况下,应该基于字段的类型。
模型应该封装一个“对象”的各个方面,遵循 Martin Fowler 的 Active Record 设计模式。
这就是为什么在模型类中要同时定义一个模型表现的数据以及关于它的信息(包括其人类可读的名称,默认排序等选项);所有用于理解给定模型所需的信息都应该存储在模型中。
数据库API的主要用处:
应该尽可能少地执行SQL语句,并且应该在内部优化语句。
这就是为什么开发者需要显式地调用 save()
,而不是由框架静默地在幕后保存东西。
这也是为什么 select_related()
QuerySet
方法存在的原因。在查询“每个关联的对象”的常见情况下,它是一个可选的性能提升器。
数据库 API 应该允许用尽可能少的语法,来表达丰富、达意的语句。它不应该依赖于导入其他模块或辅助对象。
当必要时, 在幕后插入应该是自动进行的.
每一个对象都应该能够访问所有相关的对象, 系统范围. 这种访问应该是双向的.
应该认识到数据库 API 只是一个便捷的方法,但并不必须是最终的全部手段。框架应该可以很容易地编写自定义的 SQL——完整的语句,或者仅仅是自定义 WHERE
子句作为 API 调用时的自定义参数。
Django 应用中的 URL 不应该与底层 Python 代码耦合。将 URL 与 Python 函数名联系起来是一件很糟糕且丑陋的做法。
按照这些方法,Django URL 系统应该允许同一应用的 URL 在不同的上下文中有所不同。例如,一个网站可以在 /stories/
中放置故事,而另一个网站则可以使用 /news/
。
URL 应该尽可能灵活。任何可想到的 URL 设计都应该被允许。
框架可以做到让开发者简单(或更加简单)地设计出漂亮的,而不是难看的 URL。
File extensions in web-page URLs should be avoided.
在 URL 中使用 Vignette 式的逗号应该受到严厉的惩罚。
Technically, foo.com/bar
and foo.com/bar/
are two different URLs, and
search-engine robots (and some web traffic-analyzing tools) would treat them as
separate pages. Django should make an effort to "normalize" URLs so that
search-engine robots don't get confused.
详细请参考 APPEND_SLASH
配置。
我们将模板系统看作一个工具,用于控制表现方式和表示方式相关的逻辑。模板系统不应该支持超出这个基本目标的功能。
大多数动态网站会使用一些网站整体通用的设计——一个通用的页眉、页脚、导航栏,等等。Django 模板系统应该可以很容易地将这些元素存储在一个地方,从而减少重复的代码。
这是 模板继承 背后的理念。
模板系统不应该被设计成只能输出 HTML。它应该同样擅长生成其他基于文本的格式,或者仅仅是纯文本。
使用 XML 引擎去解析模板会在编辑模板的过程中引入很多人为错误,并在模板处理中导致不可接受的开销。
模板系统不应该有的设计是,使得模板可以在WYSIWYG(所见即所得)编辑器中也能显示得很好,比如 Dreamweaver。因为这是一个非常严重的限制,会让模板的语法不够好。Django 期望模板编写者有能力直接编辑 HTML 文本。
模板系统不应该用空白符来做神奇的事情。如果模板包含空白符,系统应该在处理文本时处理空格——只是显示它。任何不在模板标签中的空白符都应该显示出来。
模板系统的目标不是发明一种编程语言。它的目标是提供足够的具有编程风格的功能,比如分支和循环,这对于做出表现相关的决策是至关重要的。Django 模板语言(DTL) 旨在避免高级逻辑。
Django 模板系统认为模板通常是由 设计师 编写的,而不是 程序员,因此不应该假设他了解 Python。
12月 13, 2021