Skip to main content

设计哲学

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

总体

松耦合

Django的堆栈的一个基本目标是 loose coupling and tight cohesion。框架的各个层不应该“知道”彼此,除非绝对必要。

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

虽然Django为了方便而提供了一个完整的堆栈,但是堆栈的各个部分尽可能独立于另一个堆栈。

少代码

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

快速开发

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

不要重复自己(DRY)

每个不同的概念和/或数据片段应该存在于一个且仅一个地方。冗余是坏的。规范化是好的。

框架,在理性之内,应尽可能少地推断。

显式优于隐式

这是 PEP 20 中列出的核心Python原则,这意味着Django不应该做太多的“魔术”。魔法不应该发生,除非有一个很好的理由。魔术是值得使用,只有当它创造了一个巨大的方便,不可能在其他方式,它没有以一种方式实施,混淆了试图学习如何使用该功能的开发人员。

一致性

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

楷模

显式优于隐式

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

包括所有相关的域逻辑

模型应该按照Martin Fowler的 Active Record 设计模式封装“对象”的每个方面。

这就是为什么在模型类中定义由模型表示的数据和关于它的信息(其人类可读的名称,诸如默认排序等选项)的原因;所有需要了解的给定模型的信息都应该存储在 in 模型中。

数据库API

数据库API的核心目标是:

SQL效率

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

这就是为什么开发人员需要显式地调用 save(),而不是框架悄悄地保存在幕后的框架。

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

强大的语法

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

在必要时,应在幕后自动执行连接。

每个对象应该能够访问系统范围内的每个相关对象。此访问应该两种方式工作。

选择在需要时轻松删除原始SQL

数据库API应该意识到它是一个快捷方式,但不一定是一个端到端的。框架应该使编写自定义SQL - 整个语句,或只是自定义 WHERE 子句作为自定义参数到API调用变得容易。

网址设计

松耦合

Django应用程序中的网址不应与底层Python代码相关联。将URL绑定到Python函数名称是一个坏和丑陋的事情。

按照这些思路,Django URL系统应该允许相同应用程序的URL在不同的上下文中是不同的。例如,一个站点可以在 /stories/ 上放置故事,而另一个站点可以使用 /news/

无限灵活性

网址应尽可能灵活。应该允许任何可想到的URL设计。

鼓励最佳做法

该框架应该使开发人员设计漂亮的URL而不是丑陋的URL一样容易(甚至更容易)。

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

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

明确的网址

从技术上讲,foo.com/barfoo.com/bar/ 是两个不同的URL,搜索引擎机器人(和一些Web流量分析工具)将它们视为单独的页面。 Django应该努力“规范化”URL,以便搜索引擎机器人不会感到困惑。

这是 APPEND_SLASH 背后的原因。

模板系统

分离逻辑与表示

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

避免冗余

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

这是 模板继承 背后的哲学。

与HTML解耦

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

XML不应用于模板语言

使用XML引擎解析模板在编辑模板时引入了一个全新的人为错误,并且在模板处理中产生了不可接受的开销水平。

假设设计师能力

不应设计模板系统,以便模板必须在所见即所得编辑器(如Dreamweaver)中正常显示。这太严格的限制,不允许语法一样好。 Django期望模板作者很容易直接编辑HTML。

明显处理空格

模板系统不应该用空格来做魔术。如果模板包含空格,系统应该将空格视为处理文本 - 只显示它。应该显示不在模板标记中的任何空格。

不要发明一种编程语言

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

Django模板系统认为模板最常由 designers 编写,而不是 programmers,因此不应假定Python知识。

安全保障

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

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

可扩展性

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

这是自定义模板标记和过滤器的理念。

视图

简单

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

使用请求对象

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

松耦合

视图不应该关心开发人员使用哪个模板系统 - 甚至是否使用模板系统。

区分GET和POST

GET和POST是不同的;开发人员应明确使用一个或另一个。框架应该使得容易区分GET和POST数据。

缓存框架

Django的 缓存框架 的核心目标是:

少代码

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

一致性

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

可扩展性

缓存API应该在基于开发人员需求的应用程序级别是可扩展的(例如,参见 缓存键转换)。