设计哲学

本文档解释了Django开发人员在创建框架时使用的一些基本理念。 它的目标是解释过去和指导未来。

整体¶ T0>

松耦合

A fundamental goal of Django’s stack is loose coupling and tight cohesion. 除非绝对必要,框架的各个层面不应该“彼此了解”。

例如,模板系统对Web请求一无所知,数据库层对数据显示一无所知,而视图系统不关心程序员使用的模板系统。

虽然Django为了方便而附带了一个完整的堆栈,但堆栈的各个部分在任何可能的情况下都是独立的。

较少的代码

Django应用程序应该使用尽可能少的代码;他们应该缺乏样板。 Django应该充分利用Python的动态功能,比如内省。

快速发展

21世纪的Web框架的重点是快速地开发Web开发的繁琐方面。 Django应该允许令人难以置信的快速Web开发。

不要重复自己(DRY)

每一个独特的概念和/或数据片段都应该只存在于一个地方。 冗余是不好的。 规范化是好的。

理性的框架应该尽可能地尽可能地推断出来。

显式优于隐式

This is a core Python principle listed in PEP 20, and it means Django shouldn’t do too much “magic.” Magic shouldn’t happen unless there’s a really good reason for it. 只有魔法创造了其他方式无法实现的巨大便利时,魔法才值得使用,而魔法不会以混淆试图学习如何使用该功能的开发人员的方式实现。

一致性¶ T0>

框架应该在各个层面上保持一致。 一致性适用于从低级(使用Python编码风格)到高级(使用Django的“体验”)的所有内容。

模型¶ T0>

显式优于隐式

字段不应仅仅基于字段的名称假设某些行为。 这需要太多的系统知识,并且容易出错。 相反,行为应该基于关键字参数,在某些情况下还应该基于字段的类型。

包含所有相关的域逻辑

Models should encapsulate every aspect of an “object,” following Martin Fowler’s Active Record design pattern.

This is why both the data represented by a model and information about it (its human-readable name, options like default ordering, etc.) are defined in the model class; all the information needed to understand a given model should be stored in the model.

数据库API

数据库API的核心目标是:

SQL效率

它应该尽可能少地执行SQ​​L语句,并且应该在内部优化语句。

This is why developers need to call save() explicitly, rather than the framework saving things behind the scenes silently.

这也是为什么存在select_related() QuerySet方法的原因。 对于选择“每个相关对象”的常见情况,这是一个可选的性能增强器。

Terse,强大的语法

数据库API应该尽可能少的语法允许丰富,表达的语句。 它不应该依赖于导入其他模块或辅助对象。

必要时,应在幕后自动进行联接。

每个对象都应该能够访问系统范围内的每个相关对象。 这种访问应该是双向的。

在需要的时候可以很容易地放入原始的SQL

数据库API应该认识到这是一个捷径,但不一定是最终的一切。 框架应该使编写自定义SQL的整个语句变得容易,或者只是自定义WHERE子句作为API调用的自定义参数。

网址设计

松耦合

Django应用程序中的URL不应与底层的Python代码耦合。 将URL绑定到Python函数名是一件坏事和丑陋的事情。

沿着这些路线,Django的URL系统应该允许同一个app的URL在不同的上下文中有所不同。 例如,一个网站可以将故事放在/stories/上,另一个可以使用/news/

无限的灵活性

网址应尽可能灵活。 任何可以想象的URL设计都应该被允许。

鼓励最佳做法

这个框架应该使开发人员设计出比丑陋的URL更容易(甚至更容易)的URL。

应避免使用网页网址中的文件扩展名。

网址中的小插曲式逗号应该受到严厉的惩罚。

明确的URL

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应该努力“规范化”URL,以便搜索引擎机器人不会感到困惑。

This is the reasoning behind the APPEND_SLASH setting.

模板系统

逻辑与表现分离

我们将模板系统看作是控制表示和表示相关逻辑的工具 - 就是这样。 模板系统不应该支持超出这个基本目标的功能。

阻止冗余

大多数动态网站使用某种常见的网站设计 - 常见的页眉,页脚,导航栏等。 Django模板系统可以很容易地将这些元素存储在一个地方,消除重复的代码。

这是template inheritance背后的原理。

从HTML 解耦

模板系统不应该被设计成只输出HTML。 它应该同样适用于生成其他基于文本的格式,或只是纯文本。

XML不应该用于模板语言

Using an XML engine to parse templates introduces a whole new world of human error in editing templates – and incurs an unacceptable level of overhead in template processing.

假设设计者的能力

不应将模板系统设计为使模板必须在所见即所得编辑器(如Dreamweaver)中正常显示。 这是太严格的限制,并不会让语法像它一样好。 Django期望模板作者可以直接编辑HTML。

明显地看待空白

模板系统不应该用空白做一些神奇的事情。 如果一个模板包含空格,那么系统应该将空格视为对待文本 - 只显示它。 应该显示不在模板标签中的任何空格。

不要发明一种编程语言

目标不是发明一种编程语言。 目标是提供足够的编程风格的功能,如分支和循环,这是做出演示相关的决定的关键。 Django模板语言(DTL)旨在避免高级逻辑。

Django模板系统认识到模板通常由设计者而不是程序员编写,因此不应该假设Python知识。

安全和安全

开箱即用的模板系统应该禁止包含恶意代码 - 例如删除数据库记录的命令。

这是模板系统不允许任意Python代码的另一个原因。

扩展¶ T0>

模板系统应该认识到高级模板作者可能想要扩展它的技术。

这是自定义模板标签和过滤器背后的原理。

观点¶ T0>

简单¶ T0>

编写视图应该像编写Python函数一样简单。 开发人员不应该在函数执行时实例化一个类。

使用请求对象

视图应该可以访问请求对象 - 一个存储关于当前请求的元数据的对象。 该对象应直接传​​递给视图函数,而不是视图函数必须从全局变量访问请求数据。 这使得它通过传入“假”请求对象来轻松,干净并且容易测试视图。

松耦合

一个视图不应该关心开发者使用哪个模板系统,或者甚至不管模板系统是否被使用。

区分GET和POST

GET和POST是不同的;开发者应该明确地使用其中之一。 该框架应该可以很容易地区分GET和POST数据。

缓存框架

Django的cache framework的核心目标是:

较少的代码

缓存应该尽可能快。 因此,围绕缓存后端的所有框架代码应该保持在绝对最小值,特别是对于get()操作。

一致性¶ T0>

缓存API应该在不同的缓存后端之间提供一致的接口。

扩展¶ T0>

根据开发人员的需求,缓存API应该在应用程序级别可扩展(例如,请参阅Cache key transformation)。