我們繼續(xù)教程1的部分開始。我們將要建立數(shù)據(jù)庫,創(chuàng)建你的第一個模型,并且快速簡介django的自動生成后臺管理系統(tǒng)。
數(shù)據(jù)庫設置
現(xiàn)在,打開mysite/settings.py。這是一個常規(guī)的模塊級別的變量來表示django設置的python模塊。
默認情況,配置使用的是SQLite。如果你是一個數(shù)據(jù)庫方面的新手,或者只是對使用django感興趣,這是最簡單的選擇。SQLite被包含在Python中,所以你不必再進行任何安裝來支持數(shù)據(jù)庫。當開始一個真正的項目時,你可能想使用擴展性更好的數(shù)據(jù)庫,以避免開發(fā)過程中數(shù)據(jù)庫切換的痛苦,例如PostgreSQL。
如果你想用其他的數(shù)據(jù)庫,安裝適當?shù)?a target="_blank" rel="nofollow">database bindings,并且修改數(shù)據(jù)庫中’default‘項來匹配你的數(shù)據(jù)庫連接設置:
- ENGINE,可以是'django.db.backends.sqlite3', 'django.db.backends.postgresql', 'django.db.backends.mysql', or 'django.db.backends.oracle',其他也是可以的,請看 also available。
- NAME,數(shù)據(jù)庫的名字,如果你使用的是SQLite,數(shù)據(jù)庫就是你的電腦上的一個文件,既然這樣,NAME應該是絕對路徑,并包括文件名。默認值os.path.join(BASE_DIR, 'db.sqlite3'),將會把文件存儲在你的項目目錄下。
如果你沒有使用SQLite作為你的數(shù)據(jù)庫,要添加USER,PASSWORD,HOST項配置。更多細節(jié)請參考文檔DATABASES。
除了SQLite意外的數(shù)據(jù)庫
如果你使用除了SQLite以外的數(shù)據(jù)庫,請確保你已經(jīng)創(chuàng)建了數(shù)據(jù)庫??梢栽谀愕臄?shù)據(jù)庫可交互命令行中,使用命令“CREATE DATABASE database_name;”。
還要確保數(shù)據(jù)庫用戶在mysite/settings.py中提供了“創(chuàng)建數(shù)據(jù)庫”的權限。在稍后的教程中,這將允許自動生成一個test數(shù)據(jù)庫。
如果你使用SQLite,你不必創(chuàng)建任何東西,當它被需要時會自動創(chuàng)建。
當你編輯mysite/settings.py時,設置TIME_ZONE為你所在的時區(qū)。
同時還要注意,在文件上方的INSTALL_APP設置,這里控制了django實例的應用的所有名字。應用可以被用在多個項目中,其他人可以通過打包和部署它們在他人的項目中。
默認情況下,INSTALL_APP包含了下面的應用,所有都是django創(chuàng)建的:
-
django.contrib.admin:后臺管理網(wǎng)站,稍后你就會用到它。 -
django.contrib.auth:一個身份驗證系統(tǒng)。 -
django.contrib.contenttypes:一個內(nèi)容類型的框架。 -
django.contrib.sessions:一個session框架。 -
django.contrib.messages:一個消息框架。 -
django.contrib.staticfiles:一個管理靜態(tài)文件的框架。
常見情況下,這些應用都會被包含在內(nèi)。
這些應用中的一些需要至少一張數(shù)據(jù)庫表才能使用,所以,我們需要先在數(shù)據(jù)庫中創(chuàng)建表,然后再使用它們。為了達到目的,我們先運行下面的命令:
$ python manage.py migrate
migrate命令關注著INSTALL_APP的設置,根據(jù)mysite/settings.py數(shù)據(jù)庫的設置來創(chuàng)建了一切必須的數(shù)據(jù)庫表,數(shù)據(jù)遷移會隨著應用進行裝載。你可以看到每條數(shù)據(jù)庫遷移記錄。如果你對此感興趣,運行你的數(shù)據(jù)庫命令行,輸入\dt (PostgreSQL), SHOW TABLES; (MySQL), .schema (SQLite), or SELECT TABLE_NAME FROM USER_TABLES; (Oracle) 用來展示django創(chuàng)建的表。
最小的應用
就像上面我們提到的,一般情況都是包含這些默認應用的,但是,并不是所有人都需要它們,如果你不需要它們,可以注釋或者適當?shù)膭h除INSTALL_APP中的某一行在運行數(shù)據(jù)庫遷移命令之前。migrate命令只會遷移INSTALL_APP中的應用程序。
創(chuàng)建模型
現(xiàn)在我們將定義你的模型,實際上是用額外添加的元數(shù)據(jù)布局你的數(shù)據(jù)庫。
哲學
模型是單一的,它定義了你的數(shù)據(jù)真實的數(shù)據(jù)源,包含了基本的字段和數(shù)據(jù)行為。Django遵循DRY原則(DRY Principle
)。目標是在一處定義數(shù)據(jù)模型,并且可以自動從它里面派生子類。
這包含了數(shù)據(jù)遷移,不像ruby on rails,例如,數(shù)據(jù)遷移是完全派生自你的數(shù)據(jù)模型文件,本質上是歷史記錄,Django可以通過update數(shù)據(jù)庫事件回滾來匹配你的當前模型。
在我們的投票應用中,我們將創(chuàng)建兩個模型:Question和Choise。Question有兩個字段question和publication date。Choise有兩個字段:文本字段choise和投票記錄字段。每個Choise都關聯(lián)到一個Question。
這些概念都有簡單的Python類來表示。編輯polls/models.py文件,就像下面這樣:

代碼意思很明顯。每個模型都由類django.db.models.Model的子類來表示,每個模型都由若干個類變量,用來表示模型中的數(shù)據(jù)庫字段。
每個字段都由Field類的實例來表示-比如CharField表示字符字段,DateTimeField表示時間字段。這會告訴Django每個字段應該保存為什么數(shù)據(jù)類型。
每個Field實例的名字就是字段的名字(例如,question_text或者pub_date),這是對機器友好的方式。你將會在你的python代碼中使用這些值,并且你的數(shù)據(jù)庫將會用它做列名。
你能使用一個可選的第一個位置參數(shù)來設計一個可讀性高的名字,這將會用于Django的自省功能,它將作為文檔被替換。如果這個字段沒有被提供,Django將使用對機器友好的名字。在這個例子中,我們只會對Question.pub_date定義可讀性高的名字設置。這個模型的其他字段,將以機器友好的方式設置,因為這足以滿足人類的可讀性要求。
一些Field類需要必須的參數(shù)。CharField,例如,需要你傳遞一個max_length參數(shù)。不僅用于數(shù)據(jù)庫模式,也會在驗證中使用,我們稍后會看到。
一個Field可以有不同的可選參數(shù),在這種情況下,我們將把votes字段的default屬性設為0。
最后,注意關系的定義,要使用ForeignKey。這會告訴Django每個Choise被關聯(lián)到一個Question。Django支持所有常見的數(shù)據(jù)庫關系:多對一,多對多,一對一。
激活模型
這些一小段代碼給予Django很多信息。隨之,Django會這樣做:
- 為這個應用創(chuàng)建一個數(shù)據(jù)庫模式(CREATE TABLE statements)
- 創(chuàng)建一個訪問Question和Choise對象的python API
但是,我們首先應該告訴項目polls應用已經(jīng)被安裝了。
哲學
Django應用是“可插拔式”的:你可以將一個應用用于多個項目中,并且可以分布式應用,因為他們不必綁定到Django上安裝。
為了在我們的項目中包含應用,我們需要參考配置類中的INSTALL_APPS。PollsConfig類在polls/apps.py文件中,所以,它的點路徑是'polls.apps.PollsConfig'。編輯mysite/settings.py文件,添加點路徑到INSTALL_APPS設置中,看起來是這樣的:

現(xiàn)在Django知道已經(jīng)包含了polls應用了,讓我們運行一條命令:
$ python manage.py makemigrations polls
你將會看到類似如下的顯示:

通過運行makemigrations,你是在告訴Django,你更改了模型文件,并且你希望這些改變作為一次數(shù)據(jù)遷移被存儲。
Migrations是Django存儲你改變模型的記錄(并且影響你的數(shù)據(jù)庫模式)-他們僅僅是磁盤上的文件。如果你喜歡,可以閱讀你模型的遷移記錄,比如polls/migrations/0001_initial.py文件。不必擔心,你不必每次Django生成時都閱讀它們,它們設置為可以人為編輯的,目的是讓你可以手動更改Django的改動。
這有一個命令將會為你運行數(shù)據(jù)遷移,并且自動管理你的數(shù)據(jù)庫模式,它叫migrate,我們稍后就會接觸到它。但是首先,讓門看看migration運行了什么SQL。sqlmigrate命令加上數(shù)據(jù)遷移的名字就能返回執(zhí)行了什么SQL。
$ python manage.py sqlmigrate polls 0001
你應該看到類似下面的輸出(為了提高可讀性,我們進行了格式化):

注意下面的事項:
- 下面確切的輸出會取決于你使用的數(shù)據(jù)庫,上面的輸出是PostgreSQL的。
- 表名是根據(jù)應用的名字自動生成的,就是模塊的名字的小寫-question和choise。(你可以重寫這個特性)
- 主鍵(IDs)是自動添加的(這個特性同樣可以重寫)
- 依照慣例,Django添加了'_id'外鍵字段(同樣可以重寫)
- 外鍵關系是由FOREIGN KEY限制的。不用擔心DEFERRABLE部分,那僅僅是告訴postgreSQL不要在事務的末尾強制執(zhí)行。
- 為你的數(shù)據(jù)庫量身定制,明確數(shù)據(jù)庫的字段類型,例如auto_increment(MySQL),serial(PostgreSQL),或者integer primary key autoincrement(SQLite)會自動處理,同樣適用于字段名,例如,適用單引號或者雙引號。
- sqlmigrate命令并沒有實際地對數(shù)據(jù)庫進行數(shù)據(jù)遷移,它僅僅是打印到屏幕上,目的是讓你知道執(zhí)行了什么SQL,Django認為這是必須的。這對查看django即將要做什么操作是很有用的,在數(shù)據(jù)庫管理員要查看SQL腳本時。
如果你感興趣,你可以運行python manage.py check,這會檢查項目中的問題,并不會做數(shù)據(jù)遷移,也不會涉及到數(shù)據(jù)庫:
$ python manage.py migrate
image.png
migrate命令會獲取所有的未被應用的數(shù)據(jù)遷移信息(Django會在你的數(shù)據(jù)庫中用一個叫’django_migrations‘的表來記錄哪些數(shù)據(jù)遷移記錄被應用了),并在數(shù)據(jù)庫上運行-本質上來講,你修改模型的時候會同步修改數(shù)據(jù)庫模式。
Migrations是非常有用的,讓你可以在開發(fā)項目時隨著時間改變模型,而不用刪除原有的表再次新建表-它專注于動態(tài)更新數(shù)據(jù)庫,在不丟失數(shù)據(jù)的情況下。在之后的教程部分,我們會更深層次的封裝他們,但是現(xiàn)在,記住三步來指導你修改模型:
- 修改模型(在models.py文件中)
- 運行python manage.py makemigrations來為這些改變創(chuàng)建遷移記錄
- 運行python manage.py migrate來應用這些改變到數(shù)據(jù)庫上。
把創(chuàng)建遷移記錄和應用遷移記錄命令分開的原因是因為,你需要提交migration到你的版本控制系統(tǒng),并裝載到你的應用程序上,這不僅僅讓你的開發(fā)更簡單,也讓其他開發(fā)者更有用。
閱讀 django-admin documentation來查看manage.py能做的全部信息。
使用API
現(xiàn)在,讓我們打開python shell來使用django給你提供的免費API。激活python shell,使用下面的命令:
$ python manage.py shell
我們使用這個命令來代替簡單的"python",因為manage.py設置了DJANGO_SETTINGS_MODULE環(huán)境變量,會把Django和python的路徑導入到mysite/settings.py文件中。
一旦你進入到shell中,瀏覽 database API。

等一下,<Question: Question object (1)>不是對象的有用的表達方式。讓我們通過修改Question模型修復這個問題(在polls/models.py文件中),并且在Question和Choise中都添加一個str()方法。

添加str()方法對你的模型來說很重要,不僅僅是在處理時出現(xiàn)提示符以給你自己提供方便,更因為對象的表達形式會被django自動生成管理。
注意這些都是普通的python方法,為了示范,讓我們自定義一個方法。

注意添加的import datetime和from django.utils import timezone,引用了python的標準庫中的datetime模塊,并且Django的時區(qū)相關的工具在django.utils.timezone中,如果你對Python中的處理時區(qū)問題不太熟悉,你可以在 time zone support docs了解更多。
保存這些改變,打開一個新的python shell,再次運行python manage.py shell。

想了解更多關于模型關系的信息,可以看 Accessing related objects。查看怎樣使用雙下劃線執(zhí)行字段通過API查找,可以看Field lookups。更多數(shù)據(jù)庫API的詳細信息,可以看 Database API reference。
介紹Django Admin
哲學
為你的員工或者客戶生成后臺管理系統(tǒng),來進行添加,刪除,修改內(nèi)容是冗長乏味且缺乏創(chuàng)造性的工作。為此,Django完全自動模型的管理界面。
Django誕生于報社,非常清楚的分離了“發(fā)布內(nèi)容”和“公共”網(wǎng)站。網(wǎng)站管理者使用系統(tǒng)來添加新聞故事,事件,體育消息等等,這些內(nèi)容都是在“公共”網(wǎng)站上的。Django解決了管理網(wǎng)站和編輯內(nèi)容都在同一個網(wǎng)站界面的問題。
Admin不打算讓客戶訪問,它是網(wǎng)站管理者使用的。
創(chuàng)建一個管理員用戶
首先,我們得創(chuàng)建一個可以訪問admin網(wǎng)站的用戶,運行如下命令:
$ python manage.py createsuperuser
輸入你期望的用戶名,然后按回車:
Username: admin
然后會提示你輸入你期望的郵箱地址:
Eamil Address: admin@example.com
下一步是輸入你的密碼,你需要輸入兩次,第二次輸入是為了確認是否和第一次相同。
Password: ******
Password(again): *****
Superuser created succesfully.
啟動開發(fā)服務器
Django的后臺管理系統(tǒng)默認是被激活了的,讓我們啟動開發(fā)者服務器,并在瀏覽器中查看。
如果服務器沒有啟動,可以這樣做:
$ python manage.py runserver
現(xiàn)在打開瀏覽器,跳到本地域名的'/admin/'路徑下,例如 http://127.0.0.1:8000/admin/,你應該在屏幕上看到用戶登錄的頁面:

translation默認是被開啟了的。登錄頁面也許會展示你所使用的語言,這取決于你的瀏覽器的設置,以及Django是否翻譯了這門語言。

你應該看到了幾種可編輯的內(nèi)容:groups和users。是django.contrib.auth提供的,驗證框架由Django進行裝載。
讓polls應用可以在admin中被編輯
但是我們的poll應用在哪呢?它沒有顯示在admin的首頁。
我們只需要做一件事:我們需要告訴admin,Question對象有一個管理界面。為了達到目的,打開polls/models.py文件,并編輯它:

瀏覽功能不受限的admin
現(xiàn)在我們注冊了Question,Django知道應該把它展示在首頁上了:

點擊“Question”,現(xiàn)在你就進入到了question的“change list”頁面了。這個頁面會展示數(shù)據(jù)庫中所有的question對象的列表,讓你可以選擇一個并改變它。

點擊“what’s up”,詢問是否更改。

這有一些問題需要注意:
- 這個表單是Question模型自動生成的
- 不同類型的模型字段(DateTimeField,CharField)根據(jù)適當?shù)腍TML輸入。每個字段在admin中都知道如何展示。
- 每個DateTimeField不收js的束縛,日期獲取“今天”并在日歷中彈出,并獲取今天的日期,便捷的彈出當前可用列表。
下面的部分給你幾個選項:
- Save-保存更改,返回這個類型對象的“change-list”頁面
- Save and continue editing- 保存更改,并重新加載這個對象的管理頁面
- Save and add another-保存更改,新建一個這個對象的空表單。
- Delete-展示一個確認刪除的頁面
如果"Date Pulisher"的值和你在教程1中創(chuàng)建的時間不匹配時,這可能意味著你沒有正確的設置時區(qū)”TIME_ZONE”,修改它,刷新頁面,返現(xiàn)正確的值出現(xiàn)了。
修改“Date publisher”通過點擊"Today"和"now"標簽,然后再點擊"Save and continue editing"。然后點擊右上方的"history"。你會看到通過django admin進行所有改動的頁面,有時間戳,用戶名(誰修改的):

當你了解了模型的API時,并熟悉了django admin時,請閱讀 part 3 of this tutorial來學習如何給polls應用添加更多的視圖。
