{% raw %}
# Django 初探 #
由于Django是在一個快節奏的新聞編輯室環境下開發出來的,因此它被設計成讓普通的網站開發工作簡單而快 捷。以下簡單介紹了如何用 Django 編寫一個數據庫驅動的Web應用程序。
本文檔的目標是給你描述足夠的技術細節能讓你理解Django是如何工作的,但是它并不表示是一個新手指南或參考目錄 – 其實這些我們都有! 當你準備新建一個項目,你可以 *從新手指南開始* 或者 *深入閱讀詳細的文檔*.
## 設計你的模型(model) ##
盡管你在 Django 中可以不使用數據庫,但是它提供了一個完善的可以用 Python 代碼描述你的數據庫結構的對象關聯映射(ORM)。
*數據模型語法* 提供了許多豐富的方法來展現你的模型 – 到目前為止,它已經解決了兩個多年積累下來數據庫架構問題。下面是個簡單的例子,可能被保存為 mysite/news/models.py:
```
class Reporter(models.Model):
full_name = models.CharField(max_length=70)
def __unicode__(self):
return self.full_name
class Article(models.Model):
pub_date = models.DateField()
headline = models.CharField(max_length=200)
content = models.TextField()
reporter = models.ForeignKey(Reporter)
def __unicode__(self):
return self.headline
```
## 安裝它 ##
下一步,運行 Django 命令行工具來自動創建數據庫表:
```
manage.py syncdb
```
syncdb 命令會查找你所有可用的模型(models)然后在你的數據庫中創建還不存在的數據庫表。
## 享用便捷的 API ##
接著,你就可以使用一個便捷且功能豐富的 *Python API* 來訪問你的數據。API 是動態生成的,不需要代碼生成:
```
# 導入我們在 "news "應用中創建的模型。
>>> from news.models import Reporter, Article
# 在系統中還沒有 reporters 。
>>> Reporter.objects.all()
[]
# 創建一個新的 Reporter 。
>>> r = Reporter(full_name='John Smith')
# 將對象保存到數據庫。你需要顯示的調用 save() 方法。
>>> r.save()
# 現在它擁有了一個ID。
>>> r.id
1
# 現在新的 reporter 已經存在數據庫里了。
>>> Reporter.objects.all()
[<Reporter: John Smith>]
# 字段被表示為一個 Python 對象的屬性。
>>> r.full_name
'John Smith'
# Django 提供了豐富的數據庫查詢 API。
>>> Reporter.objects.get(id=1)
<Reporter: John Smith>
>>> Reporter.objects.get(full_name__startswith='John')
<Reporter: John Smith>
>>> Reporter.objects.get(full_name__contains='mith')
<Reporter: John Smith>
>>> Reporter.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Reporter matching query does not exist. Lookup parameters were {'id': 2}
# 創建一個 article.
>>> from datetime import date
>>> a = Article(pub_date=date.today(), headline='Django is cool',
... content='Yeah.', reporter=r)
>>> a.save()
# 現在 article 已經存在數據庫里了。
>>> Article.objects.all()
[<Article: Django is cool>]
# Article 對象有 API 可以訪問到關聯到 Reporter 對象。
>>> r = a.reporter
>>> r.full_name
'John Smith'
# 反之亦然:Reporter 對象也有訪問 Article 對象的API。
>>> r.article_set.all()
[<Article: Django is cool>]
# API 會在幕后高效的關聯表來滿足你的關聯查詢的需求。
# 以下例子是找出名字開頭為 "John" 的 reporter 的所有 articles 。
>>> Article.objects.filter(reporter__full_name__startswith="John")
[<Article: Django is cool>]
# 通過更改一個對象的屬性值,然后再調用 save() 方法來改變它。
>>> r.full_name = 'Billy Goat'
>>> r.save()
# 調用 delete() 方法來刪除一個對象。
>>> r.delete()
```
## 一個動態的管理接口:它不僅僅是個腳手架 – 還是個完整的房子 ##
一旦你的 models 被定義好,Django 能自動創建一個專業的,可以用于生產環境的 *管理界面* – 一個可讓授權用戶添加,修改和刪除對象的網站。它使用起來非常簡單只需在你的 admin site 中注冊你的模型即可。:
```
# In models.py...
from django.db import models
class Article(models.Model):
pub_date = models.DateField()
headline = models.CharField(max_length=200)
content = models.TextField()
reporter = models.ForeignKey(Reporter)
# In admin.py in the same directory...
import models
from django.contrib import admin
admin.site.register(models.Article)
```
這種設計理念是你的網站一般是由一個員工,或者客戶,或者僅僅是你自己去編輯 – 而你應該不會想要僅僅為了管理內容而去創建后臺界面。
在一個創建 Django 應用的典型工作流中,首先需要創建模型并盡可能快地啟動和運行 admin sites, 讓您的員工(或者客戶)能夠開始錄入數據。然后,才開發展現數據給公眾的方式。
## 設計你的 URLs ##
一個干凈的,優雅的 URL 方案是一個高質量 Web 應用程序的重要細節。 Django 鼓勵使用漂亮的 URL 設計,并且不鼓勵把沒必要的東西放到 URLs 里面,像 .php 或 .asp.
為了給一個 app 設計 URLs,你需要創建一個 Python 模塊叫做 [URLconf](/topics/http/urls)。這是一個你的 app 內容目錄, 它包含一個簡單的 URL 匹配模式與 Python 回調函數間的映射關系。這有助于解耦 Python 代碼和 URLs 。
這是針對上面 Reporter/Article 例子所配置的 URLconf 大概樣子:
```
from django.conf.urls import patterns
urlpatterns = patterns('',
(r'^articles/(\d{4})/$', 'news.views.year_archive'),
(r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
)
```
上面的代碼映射了 URLs ,從一個簡單的正則表達式,到 Python 回調函數(“views”)所在的位置。 正則表達式通過圓括號來“捕獲” URLs 中的值。當一個用戶請求一個頁面時, Django 將按照順序去匹配每一個模式,并停在第一個匹配請求的 URL 上。(如果沒有匹配到, Django 將會展示一個404的錯誤頁面。) 整個過程是極快的,因為在加載時正則表達式就進行了編譯。
一旦有一個正則表達式匹配上了,Django 將導入和調用對應的視圖,它其實就是一個簡單的 Python 函數。每個視圖將得到一個 request 對象 – 它包含了 request 的 meta 信息 – 和正則表達式所捕獲到的值。
例如:如果一個用戶請求了個 URL “/articles/2005/05/39323/”, Django 將會這樣調用函數 news.views.article_detail(request, '2005', '05', '39323').
## 編寫你的視圖(views) ##
每個視圖只負責兩件事中的一件:返回一個包含請求頁面內容的 HttpResponse 對象; 或拋出一個異常如 Http404 。至于其他就靠你了。
通常,一個視圖會根據參數來檢索數據,加載一個模板并且根據該模板來呈現檢索出來的數據。 下面是個接上例的 year_archive 例子
```
def year_archive(request, year):
a_list = Article.objects.filter(pub_date__year=year)
return render_to_response('news/year_archive.html', {'year': year, 'article_list': a_list})
```
這個例子使用了 Django 的 [模板系統](/topics/templates),該模板系統功能強大且簡單易用,甚至非編程人員也會使用。
設計你的模板(templates)
上面的例子中載入了 news/year_archive.html 模板。
Django 有一個模板搜索路徑板,它讓你盡可能的減少冗余而重復利用模板。在你的 Django設置中,你可以指定一個查找模板的目錄列表。如果一個模板沒有在這個 列表中,那么它會去查找第二個,然后以此類推。
假設找到了模板 news/year_archive.html 。下面是它大概的樣子:
```
{% extends "base.html" %}
{% block title %}Articles for {{ year }}{% endblock %}
{% block content %}
<h1>Articles for {{ year }}</h1>
{% for article in article_list %}
<p>{{ article.headline }}</p>
<p>By {{ article.reporter.full_name }}</p>
<p>Published {{ article.pub_date|date:"F j, Y" }}</p>
{% endfor %}
{% endblock %}
```
變量使用雙花括號包圍。`{{ article.headline }} 表示 “輸出 article 的 headline 屬性”。而點符號不僅用于表示屬性查找,還可用于字典的鍵值查找、索引查找和函數調用。
注意 `{{ article.pub_date|date:"F j, Y" }}` 使用了 Unix 風格的“管道”(“|”符合)。這就是所謂的模板過濾器,一種通過變量來過濾值的方式。本例中,Python datetime 對象被過濾成指定的格式(在 PHP 的日期函數中可以見到這種變換)。
你可以無限制地串聯使用多個過濾器。你可以編寫自定義的過濾器。你可以定制自 己的模板標記,在幕后運行自定義的 Python 代碼。
最后,Django 使用了“模板繼承”的概念:這就是 `{% extends "base.html" %}` 所做的事。它意味著 “首先載入名為 ‘base’ 的模板中的內容到當前模板,然后再處理本模板中的其余內容。”總之,模板繼承讓你在模板間大大減少冗余內容:每一個模板只需要定義它獨特的部分即可。
下面是使用了 *靜態文件* 的 “base.html” 模板的大概樣子:
```
{% load staticfiles %}
<html>
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<img src="{% static "images/sitelogo.png" %}" alt="Logo" />
{% block content %}{% endblock %}
</body>
</html>
```
簡單地說,它定義了網站的外觀(含網站的 logo ),并留下了個“洞”讓子模板來填充。這使站點的重新設計變得非常容易,只需改變一個文件 – “base.html” 模板。
它也可以讓你創建一個網站的多個版本,不同的基礎模板,而重用子模板。 Django 的創建者已經利用這一技術來創造了顯著不同的手機版本的網站 – 只需創建一個新的基礎模板。
請注意,如果你喜歡其他模板系統,那么你可以不使用 Django 的模板系統。 雖然 Django 的模板系統特別集成了 Django 的模型層,但并沒有強制你使用它。同理,你也可以不使用 Django 的數據庫 API。您可以使用其他數據庫抽象層,您可以讀取 XML 文件,你可以從磁盤中讀取文件,或任何你想要的方法去操作數據。 Django 的每個組成部分: 模型、視圖和模板都可以解耦,以后會談到。
## 這僅僅是一點皮毛 ##
這里只是簡要概述了 Django 的功能。以下是一些更有用的功能:
一個 *緩存框架* 可以與 memcached 或其他后端緩存集成。
一個 *聚合框架* 可以讓創建 RSS 和 Atom 的 feeds 同寫一個小小的 Python 類一樣容易。
更性感的自動創建管理站點功能 – 本文僅僅觸及了點皮毛。
顯然,下一步你應該 下載 Django,閱讀 [入門教程](/intro/tutorial01) 并且加入 *社區*. 感謝您的關注!
> 譯者:[Django 文檔協作翻譯小組](http://python.usyiyi.cn/django/index.html),原文:[Overview](https://docs.djangoproject.com/en/1.8/intro/overview/)。
>
> 本文以 [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/cn/) 協議發布,轉載請保留作者署名和文章出處。
>
> [Django 文檔協作翻譯小組](http://python.usyiyi.cn/django/index.html)人手緊缺,有興趣的朋友可以加入我們,完全公益性質。交流群:467338606。
{% endraw %}
- 新手入門
- 從零開始
- 概覽
- 安裝
- 教程
- 第1部分:模型
- 第2部分:管理站點
- 第3部分:視圖和模板
- 第4部分:表單和通用視圖
- 第5部分:測試
- 第6部分:靜態文件
- 高級教程
- 如何編寫可重用的應用
- 為Django編寫首個補丁
- 模型層
- 模型
- 模型語法
- 元選項
- 模型類
- 查詢集
- 執行查詢
- 查找表達式
- 模型的實例
- 實例方法
- 訪問關聯對象
- 遷移
- 模式編輯器
- 編寫遷移
- 高級
- 管理器
- 原始的SQL查詢
- 聚合
- 多數據庫
- 自定義查找
- 條件表達式
- 數據庫函數
- 其它
- 遺留的數據庫
- 提供初始數據
- 優化數據庫訪問
- 視圖層
- 基礎
- URL配置
- 視圖函數
- 快捷函數
- 裝飾器
- 參考
- 內建的視圖
- TemplateResponse 對象
- 文件上傳
- 概覽
- File 對象
- 儲存API
- 管理文件
- 自定義存儲
- 基于類的視圖
- 概覽
- 內建顯示視圖
- 內建編輯視圖
- API參考
- 分類索引
- 高級
- 生成 CSV
- 生成 PDF
- 中間件
- 概覽
- 內建的中間件類
- 模板層
- 基礎
- 面向設計師
- 語言概覽
- 人性化
- 面向程序員
- 表單
- 基礎
- 概覽
- 表單API
- 內建的Widget
- 高級
- 整合媒體
- 開發過程
- 設置
- 概覽
- 應用程序
- 異常
- 概覽
- django-admin 和 manage.py
- 添加自定義的命令
- 測試
- 介紹
- 部署
- 概述
- WSGI服務器
- 部署靜態文件
- 通過email追蹤代碼錯誤
- Admin
- 管理操作
- 管理文檔生成器
- 安全
- 安全概述
- 說明Django中的安全問題
- 點擊劫持保護
- 加密簽名
- 國際化和本地化
- 概述
- 本地化WEB UI格式化輸入
- “本地特色”
- 常見的網站應用工具
- 認證
- 概覽
- 使用認證系統
- 密碼管理
- 日志
- 分頁
- 會話
- 數據驗證
- 其它核心功能
- 按需內容處理
- 重定向
- 信號
- 系統檢查框架