第一章 Django與模式
================
在這一章,我們討論以下話題:
我們為什么選擇Django?
Django是工作原理
什么是模式?
常見的模式合集
Django中的模式
我們為什么選擇Django?
------------------------------
每個web應用都不盡相同,就像一件手工制作的家具一樣。你幾乎會很少發現大批量的生成能夠完美地達到你的需求。即使你從一個基本需求開始,比如一個博客或者一個社交網絡,你都需要緩慢地開發,
這就是類似Django或者Rails的web框架非常流行的原因。框架加速了開發,而且它帶有很多練好的經過實踐的內容。
Python可能比其他流行的編程語言具有更多的web框架。
開箱即用的admin接口,它是Django才有的獨一無二的特點,早些時候,特別是在數據記錄和測試方面它大有裨益。而Django的開發文檔作為一個出色的開源項目早已是備受贊譽。
最后,Django在多個高流量的網站中歷經實戰的考驗。它對于常見的攻擊比如跨站腳本和跨站請求攻擊有著異常敏銳觀察。
盡管,在理論上,可能對于所有類型的網站Django不是最佳選擇,你可以是使用Django構建任何類型的網站。例如,要構建一個基于web聊天的實時接口,或許你要使用Tornado,但是web引用剩下的部分你可以仍舊使用Django來完成。對于開發你要學會選擇正確的工具。
某些內建的特性,比如admin接口,如果你使用過其他的web框架或許讓你聽上去感覺有點怪怪的。為了Django的設計,就讓我們找出它是如何問世的。
<h2>Django的歷史</h2>
When you look at the Pyramids of Egypt, you would think that such a simple and minimal design must have been quite obvious. In truth, they are products of 4,000 years of architectural evolution. Step Pyramids, the initial (and clunky) design, had six rectangular blocks of decreasing size. It took several iterations of architectural and engineering improvements until the modern, glazing, and long-lasting limestone structures were invented.
當你看到埃及金字塔的歷史時,你會很明顯地認為它是一個簡單、小規模的設計。事實上,埃及人的作品是經歷了四千年建筑的進化。當你走進金字塔時就能夠發現它的原始設計(非常厚重),擁有六個矩形的階梯式遞減的大石塊。
Looking at Django you might get a similar feeling. So, elegantly built, it must have been ?awlessly conceived. ?n the contrary, it was the result of rewrites and rapid iterations in one of the most high-pressure environments imaginable—a newsroom!
再回頭來看看Django你也會有類似的感覺。因此,如果要簡潔的構建它,必須經過無知無畏的設想。
In the fall of 2003, two programmers, Adrian Holovaty and Simon Willison, working at the Lawrence Journal-World newspaper, were working on creating several local news websites in Kansas. These sites, including LJWorld.com, Lawrence.com, and KUsports.com—like most news sites were not just content-driven portals chock-
full of text, photos, and videos, but they also constantly tried to serve the needs of the local Lawrence community with applications, such as a local business directory, events calendar, classifieds, and so on.
### 一個框架的誕生
This, of course, meant lots of work for Simon, Adrian, and later Jacob Kaplan Moss who had joined their team; with very short deadlines, sometimes with only a few hours' notice. Since it was the early days of web development in Python, they had to write web applications mostly from scratch. So, to save precious time, they gradually refactored out the common modules and tools into something called "The CMS."
Eventually, the content management parts were spun off into a separate project called the Ellington CMS, which went on to become a successful commercial CMS product. The rest of "The CMS" was a neat underlying framework that was general enough to be used to build web applications of any kind.
By July 2005, this web development framework was released as Django (pronounced Jang-Oh) under an open source Berkeley Software Distribution (BSD) license.
It was named after the legendary jazz guitarist Django Reinhardt. And the rest,
as they say, is history.
### 移除魔法
Due to its humble origins as an internal tool, Django had a lot of Lawrence ?ournal?World?specific oddities. To ?ake Django truly general purpose, an effort dubbed "Removing the Lawrence" was already underway.
However, the ?ost significant refactoring effort that Django developers had to undertake was called "Removing the Magic." This ambitious project involved cleaning up all the warts Django had accumulated over the years, including a lot of magic (an informal term for implicit features) and replacing them with a more natural and explicit Pythonic code. For example, the model classes used to be imported from a magic module called django.models.*, rather than directly importing them from the models.py ?odule they were defined in.
At that time, Django had about a hundred thousand lines of code, and it was a significant rewrite of the ?PI. ?n May ?, ????, these changes, al?ost the si?e of a small book, were integrated into Django's development version trunk and released as Django release ?.??. This was a significant step toward the Django ?.?
### Django堅持做得更好
Every year, conferences called DjangoCons are held across the world for Django developers to meet and interact with each other. They have an adorable tradition
of giving a semi-humorous keynote on "why Django sucks." This could be a member of the Django community, or someone who works on competing web frameworks or just any notable personality.
Over the years, it is amazing how Django developers took these criticisms positively and mitigated them in subsequent releases. Here is a short summary of the improvements corresponding to what once used to be a shortcoming in Django and the release they were resolved in:
- New form-handling library (Django 0.96)
- Decoupling admin from models (Django 1.0)
- Multiple database support (Django 1.2)
- Managing static files better ?Django ?.??
- Better time zone support (Django 1.4)
- Customizable user model (Django 1.5)
- Better transaction handling (Django 1.6)
- Built-in database migrations (Django 1.7)
### Django是如何工作的?
要真正的欣賞Django,你需要撇開表象來看本質。它啟發你得同時也讓會讓你不知所措。如果你已經比較了解它,你可以選擇跳過這一節。
下圖:在Django應用中一個典型的web請求是如何被處理的。

前面的圖片展示了從一個訪客的瀏覽器到Django應用并返回的一個web請求的簡單歷程。如下是數字標識的路徑:
1. 瀏覽器發送請求(基本上是字節類型的字符串)到web服務器。
2. web服務器(比如,Nginx)把這個請求轉交到一個WSGI(比如,uWSGI),或者直接地文件系統能夠取出
一個文件(比如,一個CSS文件)。
3. 不像web服務器那樣,WSGI服務器可以直接運行Python應用。請求生成一個被稱為environ的Ptyhon字典,
而且,可以選擇傳遞過去幾個中間件的層,最終,達到Django應用。
4. URLconf中含有屬于應用的urls.py選擇一個視圖處理基于請求的URL的那個請求,這個請求就已經變成了
HttpRequest——一個Python字典對象。
5. 被選擇的那個視圖通常要做下面所列出的一件或者更多件事情:
通過模型與數據庫對話。
使用模板渲染HTML或者任何格式化過的響應。
返回一個純文本響應(不被顯示的)。
拋出一個異常。
6. HttpResponse對象離開Django后,被渲染為一個字符串。
7. 在瀏覽器見到一個美化的,渲染后的web頁面。
雖然某些細節被省略掉,這個解釋應該有助于欣賞Django的高級架構。它也展示了關鍵的組件所扮演的角色,比如模型,視圖,和模板。Django的很多組件都基于這幾個廣為人知設計模式。
## 什么是模式?
What is co??on between the words ?Blueprint,? ??caffolding,? and ?Maintenance?? These software development terms have been borrowed from the world of building construction and architecture. However, one of the ?ost in?uential ter?s co?es from a treatise on architecture and urban planning written in 1977 by the leading Austrian architect Christopher Alexander and his team consisting of Murray Silverstein, Sara Ishikawa, and several others.
The term "Pattern" came in vogue after their seminal work, A Pattern Language: Towns, Buildings, Construction ?volu?e ? in a five?book series? based on the astonishing insight that users know about their buildings more than any architect ever could. A pattern refers to an everyday problem and its proposed but time-tested solution.
In the book, Christopher Alexander states that "Each pattern describes a problem, which occurs over and over again in our environment, and then describes the core of the solution to that problem in such a way that you can use this solution
a million times over, without ever doing it the same way twice."
For example, the Wings Of Light pattern describes how people prefer buildings with more natural lighting and suggests arranging the building so that it is composed of wings. These wings should be long and narrow, never more than 25 feet wide. Next time you enjoy a stroll through the long well-lit corridors of an old university, be grateful to this pattern.
Their book contained 253 such practical patterns, from the design of a room to the design of entire cities. Most importantly, each of these patterns gave a name to an abstract problem and together formed a pattern language.
Re?e?ber when you first ca?e across the word déjà vu? You probably thought "Wow, I never knew that there was a word for that experience." Similarly, architects were not only able to identify patterns in their environ?ent but could also, finally, name them in a way that their peers could understand.
In the world of software, the term design pattern refers to a general repeatable solution to a commonly occurring problem in software design. It is a formalization of best practices that a developer can use. Like in the world of architecture, the pattern language has proven to be extremely helpful to communicate a certain way of solving a design problem to other programmers.
There are several collections of design patterns but some have been considerably ?ore in?uential than the others.
###四人組模式
One of the earliest efforts to study and document design patterns was a book
titled Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides, who later became known as the Gang of Four (GoF). This book is so in?uential that ?any consider the ?? design patterns in the book as fundamental to software engineering itself.
In reality, the patterns were written primarily for object-oriented programming languages, and it had code examples in C++ and Smalltalk. As we will see shortly, many of these patterns might not be even required in other programming languages with better higher-order abstractions such as Python.
The ?? patterns have been broadly classified by their type as follows?:
- Creational Patterns: These include Abstract Factory, Builder Pattern, Factory Method, Prototype Pattern, and Singleton Pattern
- Structural Patterns: These include Adapter Pattern, Bridge Pattern, Composite Pattern, Decorator Pattern, Facade Pattern, Flyweight Pattern, and Proxy Pattern
- Behavioral Patterns: These include Chain of Responsibility, Command Pattern, Interpreter Pattern, Iterator Pattern, Mediator Pattern, Memento Pattern, Observer Pattern, State Pattern, Strategy Pattern, Template Pattern, and Visitor Pattern
While a detailed explanation of each pattern would be beyond the scope of this book, it would be interesting to identify some of these patterns in Django itself:
Django中的模式與此對比:
|四人組模式 |Django組件 | 解釋 |
| ------------- |:-------------:|----------------------:|
|命令模式 |HttpRequest |把一個request封裝進一個對象
|觀察者模式 |Signals |一個對象改變狀態時,它的所有偵聽器都被通知并自動更新
|模板模式 |基于類的視圖 | 一個算法的步驟可以不用改變算法結構來重新定義子類
而這些模式是對于學習Django內部的人來說構造最有趣的,Django下面的模式可以再次分類——這也是個常見的問題。
### Django是MVC嗎?
Model-View-Controller (MVC) is an architectural pattern invented by Xerox PARC in the 70s. Being the framework used to build user interfaces in Smalltalk, it gets an early mention in the GoF book.
Today, MVC is a very popular pattern in web application frameworks. Beginners often ask the question?is Django an M?? fra?ework?
The answer is both yes and no. The MVC pattern advocates the decoupling of
the presentation layer from the application logic. For instance, while designing
an online game website API, you might present a game's high scores table as an HTML, ?ML, or co??a?separated ????? file. However, its underlying ?odel class would be designed independent of how the data would be finally presented.
MVC is very rigid about what models, views, and controllers do. However, Django takes a much more practical view to web applications. Due to the nature of the HTTP protocol, each request for a web page is independent of any other request. Django's framework is designed like a pipeline to process each request and prepare a response.
Django calls this the Model-Template-View (MTV) architecture. There is separation of concerns between the database interfacing classes (Model), request-processing classes ??iew?, and a te?plating language for the final presentation ?Te?plate?.
If you compare this with the classic MVC—"Model" is comparable to Django's Models, "View" is usually Django's Templates, and "Controller" is the framework itself that processes an incoming HTTP request and routes it to the correct view function.
If this has not confused you enough, Django prefers to name the callback function to handle each URL a "view" function. This is, unfortunately, not related to the MVC pattern's idea of a View.
MVC對于模型,視圖,和控制該做什么設定的非常嚴格。然而,到web應用Django采取的是更實用的視圖。要處理原生的HTTP協議,每個到web頁面的請求獨立于其他的請求。Django的框架設計的像一個管道處理每個請求,準備好響應。
Django稱之為模型-模板-視圖(MTV)架構。數據庫接口類(模型)和 請求處理類(視圖),以及最終表現的模板語言之間有著獨立關系。
如果你將它于經典的MVC比較,“模型”可以通Django的模型比較,“視圖”
要是這些都還不足以讓你感到迷惑,Django傾向于選擇命名回調函數處理每個URL的“視圖”函數。即,一個沒有MVC視圖概念的視圖。
### 福勒模式
In 2002, Martin Fowler wrote Patterns of Enterprise Application Architecture, which described 40 or so patterns he often encountered while building enterprise applications.
Unlike the GoF book, which described design patterns, Fowler's book was about architectural patterns. Hence, they describe patterns at a much higher level of abstraction and are largely programming language agnostic.
Fowler's patterns are organized as follows:
? Domain Logic Patterns: These include Domain Model, Transaction Script, Service Layer , and Table Module
? Data Source Architectural Patterns: These include Row Data Gateway, Table Data Gateway, Data Mapper, and Active Record
? Object-Relational Behavioral Patterns: These include Identity Map, Unit of Work, and Lazy Load
? Object-Relational Structural Patterns: These include Foreign Key Mapping, Mapping, Dependent Mapping, Association Table Mapping, Identity
Field, Serialized LOB, Embedded Value, Inheritance Mappers, Single Table Inheritance, Concrete Table Inheritance, and Class Table Inheritance
? Object-Relational Metadata Mapping Patterns: These include Query Object, Metadata Mapping, and Repository
? Web Presentation Patterns: These include Page Controller, Front Controller, Model View Controller, Transform View, Template View, Application Controller, and Two-Step View
? Distribution Patterns: These include Data Transfer Object and Remote Facade
? Offline Concurrency Patterns: These include Coarse Grained Lock, Implicit Lock, Optimistic ?f?ine Lock, and Pessi?istic ?f?ine Lock
? Session State Patterns: These include Database Session State, Client Session State, and Server Session State
? Base Patterns: These include Mapper, Gateway, Layer Supertype, Registry, Value Object, Separated Interface, Money, Plugin, Special Case, Service Stub, and Record Set
Almost all of these patterns would be useful to know while architecting a Django application. In fact, Fowler's website at http://martinfowler.com/eaaCatalog/ has an excellent catalog of these patterns. I highly recommend that you check them out.
Django also implements a number of these patterns. The following table lists a few of them:
Django中的模式與此對比:
|四人組模式 |Django組件 |解釋 |
|------------- |:-------------:|--------------------: |
|活動記錄 |Django模型 |封裝數據庫訪問,對數據添加域名邏輯
|類表繼承 |模型繼承 |繼承中的每個實體都映射到一個獨立的表
|標識自動 |Id字段 |在一個對象中保存一個數據庫ID字段以維護標識
|模板視圖 |Django模板 |使用HTML的內嵌生成器渲染到HTML
### 還有更多的模式?
Yes, of course. Patterns are discovered all the ti?e. Like living beings, so?e mutate and form new patterns: take, for instance, MVC variants such as Model–view–presenter (MVP), Hierarchical model–view–controller (HMVC), or Model View ViewModel (MVVM).
Patterns also evolve with ti?e as better solutions to known proble?s are identified. For example, Singleton pattern was once considered to be a design pattern but now is considered to be an Anti-pattern due to the shared state it introduces, similar to using global variables. An Anti-pattern can be defined as co??only reinvented but a bad solution to a problem.
Some of the other well-known books which catalog patterns are Pattern-Oriented Software Architecture (known as POSA) by Buschmann, Meunier, Rohnert, Sommerlad, and Sta; Enterprise Integration Patterns by Hohpe and Woolf; and
The Design of Sites: Patterns, Principles, and Processes for Crafting a Customer-Centered Web Experience by Duyne, Landay, and Hong.
## 本書中模式
This book will cover Django?specific design and architecture patterns, which would be useful to a Django developer. The upcoming sections will describe how each pattern will be presented.
*Pattern name*
The heading is the pattern name. If it is a well-known pattern, the commonly used name is used; otherwise, a terse, self-descriptive name has been chosen. Names are important, as they help in building the pattern vocabulary. All patterns will have the following parts:
*Problem*:? This brie?y ?entions the proble?.
*Solution*: This summarizes the proposed solution(s).
*Problem Details*: This elaborates the context of the problem and possibly gives an example.
*Solution Details*: This explains the solution(s) in general terms and provides a sample Django implementation.
本書覆蓋針對對于Django開發者會很有用的Django的設計和架構模式。接下來的章節會描述每個模式是如何實現的。
**模式名稱**
標題是模式名稱。如果它是知名的模式,常用的名字被使用;否則,簡潔的,自描述的名稱被選擇。名稱非常重要,它們有助于構建模式詞匯。所有的模式都有以下部分:
### 鑒審模式
Despite their near universal usage, Patterns have their share of criticism too. The most common arguments against them are as follows:
盡管它們近乎于通用,模式共享也有它們的審鑒共享。它們的最常見參數如下:
- Patterns compensate for the missing language features: Peter Norvig found that 16 of the 23 patterns in Design Patterns were 'invisible or simpler' in Lisp. Considering Python's introspective facilities and first?class functions, this ?ight as well be the case for Python too.
- Patterns repeat best practices: Many patterns are essentially formalizations of best practices such as separation of concerns and could seem redundant.
- Patterns can lead to over-engineering: Implementing the pattern might be less efficient and excessive co?pared to a si?pler solution.
### 如何使用模式
While some of the previous criticisms are quite valid, they are based on how patterns are misused. Here is some advice that can help you understand how best to use design patterns:
- Don't implement a pattern if your language supports a direct solution
- Don't try to retro?fit everything in ter?s of patterns
-
- Use a pattern only if it is the most elegant solution in your context
- 在開發環境中且僅當解決方法為最簡練時使用模式
- Don't be afraid to create new patterns
- 不要害怕創建新模式
>#### 最佳實踐
In addition to design patterns, there might be a recommended approach to solving a problem. In Django, as with Python, there might be several ways to solve a problem but one idiomatic approach among those.
除了設計模式之外,還是存在其他推薦的方法來解決一個問題。在Django中,因為使用的語言就是Python,所以我們就有
### Python之禪和Django的設計哲學
Generally, the Python community uses the term 'Pythonic' to describe a piece of idiomatic code. It typically refers to the principles laid out in 'The Zen of Python'. Written like a poem, it is extremely useful to describe such a vague concept.
通常來說,Python社區使用術語“Python范兒”來描述一段編寫手法地道的代碼。我們通常參照“Python之禪”中出現的原則。就像寫詩歌一樣,它在描述一個模糊的概念時及其有用。
>Try entering import this in a Python prompt to view 'The Zen of Python'.
Furthermore, Django developers have crisply documented their design philosophies while designing the framework at https://docs.djangoproject.com/en/dev/ misc/design-philosophies/.
While the document describes the thought process behind how Django was designed, it is also useful for developers using Django to build applications. Certain principles such as Don't Repeat Yourself (DRY), loose coupling, and tight cohesion can help you write more maintainable and idiomatic Django applications.
Django or Python best practices suggested by this book would be formatted in the following manner:
>#### 最佳實踐:
在settings.py中使用BASE_DIR,避免硬編碼目錄名稱。
## 總結
In this chapter, we looked at why people choose Django over other web frameworks, its interesting history, and how it works. We also examined design patterns, popular pattern collections, and best practices.
本章,我們瀏覽了為什么人們選擇Django而不是其他的Web框架,以及它的發展史,和Django的工作原理。我們也驗證了設計模式,流行的模式集合,以及最佳實踐。
In the next chapter, we will take a look at the first few steps in the beginning of a Django project such as gathering requirements, creating mockups, and setting up the project.
在下一章,我們會學習Django項目中開始的頭幾個步驟,比如獲取請求,模型建模,以及項目配置。
--------------------
? Creative Commons BY-NC-ND 3.0 | [我要訂閱](https://github.com/cundi/Django-Design-Patterns-and-Best-Practices/subscription) | [我要捐助](https://github.com/cundi/Web.Development.with.Django.Cookbook/issues/3)