Design philosophies

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

Overall

Loose coupling

Django栈的基本目标是松耦合和紧密内聚框架的各个层不应该“知道”彼此,除非绝对必要。

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

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

Less code

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

Quick development

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

Don’t repeat yourself (DRY)

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

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

也可以看看

波特兰模式库上的DRY讨论

Explicit is better than implicit

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

Consistency

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

Models

Explicit is better than implicit

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

Include all relevant domain logic

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

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

Database API

数据库API的核心目标是:

SQL efficiency

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

这就是为什么开发人员需要显式调用save(),而不是静默地保存场景。

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

Terse, powerful syntax

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

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

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

Option to drop into raw SQL easily, when needed

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

URL design

Loose coupling

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

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

Infinite flexibility

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

Encourage best practices

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

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

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

Definitive URLs

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

这是APPEND_SLASH设置背后的原因。

Template system

Separate logic from presentation

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

Discourage redundancy

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

这是template inheritance背后的哲学。

Be decoupled from HTML

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

XML should not be used for template languages

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

Assume designer competence

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

Treat whitespace obviously

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

Don’t invent a programming language

模板系统故意不允许以下操作:

  • 分配给变量
  • 高级逻辑

目标不是发明一种编程语言。目标是提供足够的编程类型的功能,如分支和循环,这对于做演示相关的决定是必不可少的。

Django模板系统认为模板最常由设计师而不是程序员写,因此不应假定Python知识。

Safety and security

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

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

Extensibility

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

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

Views

Simplicity

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

Use request objects

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

Loose coupling

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

Differentiate between GET and POST

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

Cache Framework

Django的cache framework的核心目标是:

Less code

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

Consistency

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

Extensibility

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