說明1:本文翻譯自Django官方文檔Writing your first Django app, part 1。
說明2:本文中,采用django 1.8以及Python 2.7,Debaian Linux;系統(tǒng)運行在Raspberry Pi上。
我們通過例子(example)來進(jìn)行學(xué)習(xí)。
通過本教程,我們將會創(chuàng)建一個基本的投票應(yīng)用(a basic poll application)。
它包含兩部分:
·一個公共站點,可以用來瀏覽并接受人們的投票。
·一個后臺,你可以通過它來添加、改變以及刪除投票。
我們假設(shè)你已經(jīng)安裝了Django。如果你不確定,可以通過以下命令來確定你的系統(tǒng)上是否已經(jīng)安裝Django以及Django的版本。
注1:原文中使用的為Python 3.X,本文使用Python 2.7。因為個別代碼或命令會略有不同。
$ python -c ?"import django; print django.get_version()"
如果系統(tǒng)中已經(jīng)安裝了Django,你應(yīng)該可以得到系統(tǒng)中安裝的Django的版本,如圖1所示;如果系統(tǒng)中沒有安裝Django,系統(tǒng)將會顯示一個錯誤(error):"No module named django(沒有django模塊)"。
本教程基于Django 1.8。如果你的Django版本與本教程不匹配,請升級至最新的Django 1.8。關(guān)于卸載舊版并安裝新版Django的教程可參考該教程“How to install Django"。
創(chuàng)建一個工程(Creating a project)
如果這是第一次使用Django,你需要注意一些項目初始化的步驟。也就是說,你需要通過一些Django命令來自動生成一些初始代碼來建立一個Django工程。這些初始化代碼主要包含了一些Django實例(instance of Django)的設(shè)置:數(shù)據(jù)庫設(shè)置、Django相關(guān)的設(shè)置、應(yīng)用相關(guān)的設(shè)置。
在命令行下,用cd命令進(jìn)入存儲代碼的目錄,并執(zhí)行下列命令:
$ django-admin.py startproject mysite
或者
$django-admin startproject mysite
這個命令將在你的當(dāng)前目錄下創(chuàng)建一個名為mysite的文件夾。如果該命令不能正確執(zhí)行,請參考“Problems running django-admin"。
注2:關(guān)于你所創(chuàng)建的Django Project的命名問題:請不要用Python或Django的內(nèi)建變量來進(jìn)行project命名。也就是說,你需要避免使用類似Django或者test之類的名字來命名你的Django project。
注3:關(guān)于django代碼的存放:區(qū)別于PHP,可以將代碼存放在任意你希望的位置,而不需放置在www/文件夾下。
下面我們來看看startproject命令創(chuàng)建了什么:
mysite/ ? ?項目的根目錄,是放project的容器。其命名和Django無關(guān),可以隨意修改該文件夾名
? ? ? ? manage.py ?命令行工具-可以通過它與Django project進(jìn)行互動。參考
? ? ? ? mysite/? Django project實際的Python代碼包(Python package),目錄名稱不能改變。
? ? ? ? ? ? ? ?_init_.py ? 空文件-通知Python該目錄下文件為一個Python Package。
? ? ? ? ? ? ? settings.py ?Django Project的設(shè)置文件。參考
? ? ? ? ? ? ? urls.py ? Django Project的URL聲明文件,類似基于Django的站點的“目錄”。參考
? ? ? ? ? ? ? wsgi.py ? 一個對于WSGI兼容的Web服務(wù)器的入口點。參考
數(shù)據(jù)庫設(shè)置(database setup)
現(xiàn)在我們來編輯mysite/setting.py。該文件是一個普通的Python模塊(Python module)并使用模塊級(module-level)的變量來表示Django設(shè)置。
Django項目默認(rèn)使用SQLite數(shù)據(jù)庫。如果你對數(shù)據(jù)庫并不熟悉或者只是想試一下django,那么使用SQLite是一個最簡單的選擇。SQLite包含在Python中,因此你不需要安裝其他軟件來支持你的數(shù)據(jù)庫。然而,當(dāng)你開始開發(fā)一個真正的Django項目時,你可能需要一個類似PostgreSQL的強(qiáng)健數(shù)據(jù)庫。
如果你希望使用其他數(shù)據(jù)庫,需要安裝合適的數(shù)據(jù)庫綁定(database bindings),并在DATABASES 'default'項下修改一下鍵值(keys)以適合新的數(shù)據(jù)庫連接的需要,如圖2所示:
·ENGINE-可以為'django.db.backends.sqlite3', 'django.db.backends.postgresql_psycopg2', ? 'django.db.backends.mysql', 'django.db.backends.oracle'; 其他數(shù)據(jù)庫設(shè)置參考
·NAME-數(shù)據(jù)庫名稱。如果使用SQLite,數(shù)據(jù)庫就是電腦上的一個文件。這種情況下,NAME應(yīng)該為這個數(shù)據(jù)庫文件的完整絕對路徑(包含文件名)。其默認(rèn)值為os.path.join(BASE_DIR,'db.sqlite3'),將把數(shù)據(jù)庫文件存儲在Django project的目錄下。
如果沒有使用SQLite作為數(shù)據(jù)庫,那么還需要設(shè)置USER,PASSWORD以及HOST。更多的細(xì)節(jié)可以參考相關(guān)文檔。
注4:如果使用PostgreSQL或者M(jìn)ySQL,需要在設(shè)置數(shù)據(jù)庫之前首先建立一個數(shù)據(jù)庫。一般情況下,可以在數(shù)據(jù)庫的交互命令行下,使用"CREATE DATABASE database_name;"來實現(xiàn)。如果使用SQLite則在設(shè)置數(shù)據(jù)庫之前不需要做任何事情,數(shù)據(jù)庫文件將會在需要的時候自動生成。
在編輯mysite/setting.py的時候,將TIME_ZONE設(shè)置為你的站點所在的時區(qū)。
另外,需要注意setting.py文件頂端的INSTALLED_APPS設(shè)置。這里包含了這個Django實例(Django instance)中所有激活的Django應(yīng)用(Django applications)的名稱。Django應(yīng)用可以被多個Django項目(Django project)所使用,也可以將其打包并分發(fā)給其他人的project使用。
默認(rèn)情況下,INSTALLED_APPS包含了以下應(yīng)用,其全部來自Django:
·django.contrib.admin-管理臺站點。我們將在本教程的第二部分使用它。
·django.contrib.auth-一套認(rèn)證(authentication)系統(tǒng)。
·django.contrib.contenttypes-一個內(nèi)容類型(content types)框架。
·django.contrib.sessions-一個會話(session)框架。
·django.contrib.messages-一個消息(messageing)框架。
·django.contrib.staticfiles-一個管理靜態(tài)文件(static files)的框架。
以上應(yīng)用默認(rèn)安裝,以方便一般情況下的使用。
部分以上應(yīng)用的運行至少需要用到一張數(shù)據(jù)庫表(database table)。因為我們在使用以上應(yīng)用之前需要在數(shù)據(jù)庫中創(chuàng)建數(shù)據(jù)表(tables),可以使用以命令實現(xiàn):
$ python manage.py migrate
migrate命令會根據(jù)mysite/setting.py中的數(shù)據(jù)庫設(shè)置創(chuàng)建任何在INSTALLED_APPS中需要使用的數(shù)據(jù)庫表(database tables),并且數(shù)據(jù)庫遷移(database migrations) 會與app附帶綁定(shipped with)在一起(我們將會在后面提到)。在每次遷移(migration)執(zhí)行時,你都會收到消息,如圖3所示。
如果你感興趣的話,在你數(shù)據(jù)庫的命令行里執(zhí)行以下命令以顯示Django創(chuàng)建的數(shù)據(jù)表:
\dt ? ? (PostgreSQL)
SHOW TABLES; ? (MySQL)
.schema ?(SQLite)
注5:正如我們前面所提到的,這些默認(rèn)應(yīng)用是對一般或者大多數(shù)情況而言的,并非每個項目都需要它們。如果你并不需要這些默認(rèn)應(yīng)用中的一部分或者全部,那么可以在執(zhí)行migrate命令前將其注釋掉或者在INSTALLED_APPS中直接刪除相應(yīng)的代碼行。migrate命令指揮對INSTALLED_APPS中的應(yīng)用執(zhí)行數(shù)據(jù)遷移(migration)。
開發(fā)服務(wù)器(The development server)
我們來確認(rèn)一下Django是否工作正常。在外層mysite/目錄下(project的根目錄)執(zhí)行一下命令:
$ python manage.py runserver
你將在命令行中看到一下輸出:
可以看到,你已經(jīng)開啟了Django的開發(fā)服務(wù)器。這是一個輕量級的、純粹使用Python編寫的web服務(wù)器。該web服務(wù)器包含在Django中,這樣開發(fā)者可以使用它進(jìn)行快速開發(fā),而不需要去在真實部署之前花費精力去設(shè)置生產(chǎn)壞境下的web服務(wù)器,比如Apache.
注6:請不要再正式生產(chǎn)環(huán)境下使用該web服務(wù)器,其僅適用于開發(fā)使用。
現(xiàn)在web服務(wù)器開始運行了,使用你的瀏覽器訪問http://127.0.0.1:8000/。你可以看到一個柔和的淺藍(lán)色的“Welcome to Django”頁面,如圖5所示。
注7:默認(rèn)情況下,runserver命令會在內(nèi)部ip的8000端口上開啟開發(fā)服務(wù)器。如果需要修改服務(wù)器端口,可以將端口號作為參數(shù)傳遞進(jìn)命令行,比如我們在8080端口上開啟開發(fā)服務(wù)器:
$ python manage.py runserver 8080
如果需要修改服務(wù)器的ip地址,可以將ip地址連同端口號一起傳遞。因此,如果需要監(jiān)聽所有公共ip地址(可以在其他電腦上展示你的作品)可以執(zhí)行一下命令:
$ python manage.py runserver 0.0.0.0:8000
關(guān)于開發(fā)服務(wù)器的全部文檔可以在runserver參考文檔中找到。
注8:開發(fā)服務(wù)器會對每一個請求(request)自動重載(reload)Python代碼。因此,當(dāng)代碼修改后并不需要手動重啟開發(fā)服務(wù)器。然而,有些操作(比如添加文件)并不會觸發(fā)服務(wù)器重啟,因此在這些情況下需要手動重啟服務(wù)器。
創(chuàng)建模型(Creating models)
現(xiàn)在我們的項目環(huán)境已經(jīng)搭建完畢,可以開始工作了。
每一個Django應(yīng)用都包含有一套特定規(guī)制格式的Python代碼包(Python package).Django會自動生成一個應(yīng)用的基本目錄結(jié)構(gòu),因此你只需關(guān)注代碼編寫而不必為如何創(chuàng)建應(yīng)用的文件目錄而分心。
注9:關(guān)于Django項目(Projects)和Django應(yīng)用 (apps)之間的區(qū)別。所謂app是指完成一些功能的web應(yīng)用,比如博客系統(tǒng)(weblog system),公共記錄的數(shù)據(jù)庫(a database of public records)或者是一個簡單的投票系統(tǒng)(a simple poll app)。一個Django項目(project)是指一個特定網(wǎng)站的一系列配置文件和應(yīng)用的集合。一個項目(project)可以包含多個應(yīng)用(app),一個應(yīng)用(app)可以被多個項目(project)使用。
Django應(yīng)用的代碼可以存放在Python路徑(Python path)上的任意位置。在本教程中,我們將在manage.py同目錄下創(chuàng)建poll應(yīng)用。這樣做的好處是該應(yīng)用可以作為該項目的頂級模塊被導(dǎo)入,如不需要作為mysite的子模塊。
因此,在創(chuàng)建該應(yīng)用的之前,請首先確認(rèn)處在與manage.py同一目錄下,并執(zhí)行以下命令:
$ python manage.py startapp polls
該命令會創(chuàng)建polls目錄,該目錄結(jié)構(gòu)為:
polls/
? ? ? ? _init_.py
? ? ? ? admin.py
? ? ? ? migrations/
? ? ? ? ? ? ? ? ?_init_.py
? ? ? ? models.py
? ? ? ? tests.py
? ? ? ? views.py
以上目錄結(jié)構(gòu)即為投票應(yīng)用(poll application)的目錄結(jié)構(gòu)。
使用Django編寫一個基于數(shù)據(jù)庫的web應(yīng)用的第一步是定義模型(models),其中主要包括:你的數(shù)據(jù)庫結(jié)構(gòu)(database layout)以及其他元數(shù)據(jù)(metadata)。
在我們這個簡單的poll應(yīng)用中,我們將創(chuàng)建兩個模型(models):Question和Choice。其中Question中包含問題(question)和發(fā)布時間(a publication date)。Choice中包含兩個字段(fields):選擇的內(nèi)容(the text of the choice)以及票數(shù)計算(a vote tally)。其中每一個Choice與一個Question相關(guān)聯(lián)。
以上的概念通過簡單的Python類(python classes)來實現(xiàn)。編輯polls/models.py文件:
from django.db import models
class Question(models.Model):
? ? ? question_text=models.CharField(max_length=200)
? ? ? pub_date=models.DateTimeField('date published')
class Choice(models.Model):
? ? ? question=models.ForeignKey(Question)
? ? ? choice_text=models.CharField(max_length=200)
? ? ? votes=models.IntegerField(default=0)
上述代碼非常簡單直接。每個模型(model)都通過一個django.db.models.Model的子類來表示。每個模型(model)都包含一系列的類變量(class variables),每個變量都代表了一個模型(model)中的數(shù)據(jù)庫字段(database field)。
每個字段(field)都通過一個字段類(a Field class)的實例來表示,比如:CharField表示字符字段,DateTimeField表示時間字段。這些內(nèi)容用來向Django說明每個字段(field)中所包含的數(shù)據(jù)類型。
每一個Field實例的命名(比如question_text 或者 pub_date)就是字段(field)的名稱,這是一種易于機(jī)器識別的格式(a machine-friendly format)。你可以在Python代碼中使用這些名稱,數(shù)據(jù)庫也會將其作為列名(column name)。
你也可以是使用Field類可選的第一個位置參數(shù)(positional argument)來指定一個易于理解的名稱。這一般用于django的內(nèi)省部分(introspective parts)并可以同時作為文檔使用。如果這一字段沒有提供,django將自動采用一個機(jī)器可讀(machine-readable)的名稱。在本例中,我們?yōu)?b>Question.pub_date定義了人類易讀(human-readable) 的名稱。對于該模型中的其他字段,其字段機(jī)器易讀(machine-readable)的名稱同時也是人類易讀(human-readable)的。
一些Field類需要傳遞一些必要參數(shù)(required argument),以CharField類為例,需要被傳遞一個max_length參數(shù)。這些不僅用于數(shù)據(jù)庫架構(gòu)(database schema)也同時可以用于模式(model)的激活生效。
一個Field類也可以同時具有很多可選參數(shù),比如在本例中將votes的default值設(shè)置為0。
最后,我們使用ForeignKey來進(jìn)行關(guān)系定義。這可以通知Django每個Choice只與一個Question相關(guān)聯(lián)。Django支持所有常見的數(shù)據(jù)庫關(guān)系:多對一,一對一以及多對多。
激活模型(Activating models)
我們在前面polls/models.py中編寫的那一點兒代碼可以傳遞給Django很多信息。通過這些代碼,Django可以:
·為該應(yīng)用創(chuàng)建一套數(shù)據(jù)庫架構(gòu)(database schema)(類似于CREATE TABLE命令)
·為接入(accessing)Question和Choice對象創(chuàng)建一個Python數(shù)據(jù)庫接入API(Python database-access API)。
但是,首先我們需要告知我們Django項目(project),我們已經(jīng)安裝了polls應(yīng)用。
注10:Django是“可插拔”的:你可以在多個項目中使用一個應(yīng)用,也可以分發(fā)應(yīng)用而并不需要和一個給定的Django安裝綁定在一起。
編輯mysite/settings.py,并修改INSTALED_APPS設(shè)置使其包含'polls'字符串,如圖6所示:
現(xiàn)在,Django已經(jīng)知道我們安裝了'polls'應(yīng)用。下面執(zhí)行以下命令:
$ python manage.py makemigrations polls
應(yīng)該可以得到以下顯示,如圖7所示:
通過執(zhí)行makemigrations命令,你告知Django你已經(jīng)對你的模型(models)做了一些修改(在本例中我們創(chuàng)建了新的模型)并且希望這些修改被存儲下來(you'd like the changes to be stored as a migration)。
遷移(Migrations)是Django存儲模(models)型修正以及你的數(shù)據(jù)庫架構(gòu)(database schema)的方式-其實它們只是存儲在硬盤上的文件。如果你喜歡的話,你可以閱讀你的新模型的遷移,就是polls/migrations/0001_initial.py文件。
migrate命令可以自動的執(zhí)行數(shù)據(jù)遷移(migrations)并管理你的數(shù)據(jù)庫架構(gòu)(database schema),我們將在后文中提到。首先,我們來看一下數(shù)據(jù)遷移(migration)如何執(zhí)行SQL語句。其中sqlmigrate命令以migration名稱為參數(shù)并返回SQL語句。
$ python manage.py sqlmigrate polls 0001
你應(yīng)該可以看到以下信息,如圖8所示:
下面給出一個可讀的格式,如圖9所示:
注11:sqlmigrate命令其實并沒有對你的數(shù)據(jù)庫執(zhí)行數(shù)據(jù)遷移(migration)。它只是在屏幕上顯示Django將會執(zhí)行什么SQL命令。
如果有興趣的話,你可以執(zhí)行 python manage.py check命令;這一命令會在不執(zhí)行數(shù)據(jù)遷移(migration)和不改動數(shù)據(jù)庫的情況下檢測你的Django項目中的任何問題。
現(xiàn)在,我們再次執(zhí)行migrate命令以便在數(shù)據(jù)庫中創(chuàng)建那些模式數(shù)據(jù)表(those model tables):
$ python manage.py migrate
會顯示如下信息,如圖10所示:
migrate命令會執(zhí)行所有未執(zhí)行的數(shù)據(jù)遷移(migration)(django通過數(shù)據(jù)庫中一個名為django_migrations的特殊數(shù)據(jù)表來記錄數(shù)據(jù)遷移執(zhí)行與否)并在你的數(shù)據(jù)庫架構(gòu)上同步你所對模型(models)所做的修改。
數(shù)據(jù)遷移功能十分強(qiáng)大并且可以超時(over time)修改你的模型(models)。當(dāng)你開發(fā)你的django項目時,你并不需要刪除你的數(shù)據(jù)庫或者數(shù)據(jù)表并建立新的數(shù)據(jù)庫或數(shù)據(jù)表。它可以在不丟失數(shù)據(jù)的情況下實時(live)的升級你的數(shù)據(jù)庫。我們會在該教程后面的章節(jié)中進(jìn)一步闡述這一點。現(xiàn)在,只需記住執(zhí)行模型修改(making model changes)的三個步驟:
·修改你的模型(在models.py中)
·執(zhí)行python manage.py makemigrations來創(chuàng)建這些修正的數(shù)據(jù)遷移(migration)
·執(zhí)行python manage.py migrate 將這些改變應(yīng)用到數(shù)據(jù)庫中
分別使用兩條不同的命令來創(chuàng)建(makemigrations)和應(yīng)用(migrate)數(shù)據(jù)遷移(migration)是因為你需要提交(commit)數(shù)據(jù)遷移(migration)到版本控制系統(tǒng)(version control system)并將其與app附加在一起;這些設(shè)定更加易于開發(fā)者進(jìn)行開發(fā),并且在生產(chǎn)環(huán)境中也更加易用。
對于manage.py的更多功能參考“django-admin 文檔”。
使用API(Playing with the API)
現(xiàn)在我們進(jìn)入Python的交互shell界面并操作Django API。我們可以使用一下命令進(jìn)入Python shell:
$ python manage.py shell
如圖11所示:
我們使用上述命令取代簡單的輸入“python”,是因為manage.py將DJANGO_SETTINGS_MODULE設(shè)置為環(huán)境變量,使Django可以將Python輸入路徑(Python import path)傳遞到mysite/settings.py文件中。
下面我們來看一下Django的數(shù)據(jù)庫API (database API):
首先輸入我們前面寫的polls/models.py中的Question 和 Choice 類。
from polls.models import Question, Choice ?#import the model classes we just wrote
可以看到系統(tǒng)中目前并沒有問題(question)存在,如圖12所示:
下面,我們來添加一個新的問題,執(zhí)行如下操作:
from django.utils import timezone
q=Question(question_text="What's new ?",pub_time=timezone.now())
注12:在Django項目的默認(rèn)設(shè)置文件中是可以支持時區(qū)功能的。在這里我們希望問題的發(fā)布時間(pub_time)是一個與時區(qū)相關(guān)的時間信息。因此我們使用timezone.now()取代了datetime.datetime.now()。
下面將我們新創(chuàng)建的問題對象保存入數(shù)據(jù)庫,執(zhí)行以下命令:
q.save()
執(zhí)行過數(shù)據(jù)保存命令save()后,我們的新建對象q應(yīng)該在數(shù)據(jù)庫中具有個一個ID,可通過一下命令查看:
q.id
結(jié)果如圖13所示:
注13:根據(jù)后臺使用的數(shù)據(jù)庫的不同,結(jié)果可能顯示1亦可能顯示1L。本例中使用的數(shù)據(jù)庫為SQLite。
我們還可以通過python命令查看模型字段中的其他值(access model field values):
q.question_text
q.pub_date
結(jié)果如圖14所示:
也可以在shell中改變相關(guān)參數(shù)的值,同時不要忘記保存進(jìn)數(shù)據(jù)庫:
q.question_text="what is up?"
q.save()
結(jié)果如圖15所示:
下面我們再次通過objects.all()來查看數(shù)據(jù)庫中所有已存在的問題(question),執(zhí)行下列命令:
Question.objects.all()
得到如下結(jié)果如圖16:
可以看到Question.objects.all()命令返回的信息對我們的幫助不大。我們可以通過修改polls/models.py中的Question和Choice模型來解決這個問題。具體說來就是在Question和Choice類中添加__unicode__函數(shù),如圖17所示:
注14:本文中采用python 2.7,如果使用Python 3,請使用__str__()函數(shù),具體信息可參考英文原文。
在models.py中添加__unicode__()不僅可以在交互shell界面中為程序員提供方便的信息,也在Django自動生成的后臺管理時具有重要作用。
重新開啟一個Python shell,確認(rèn)我們的修改時候生效,如圖18所示:
可以看到,我們在polls/models.py中的修改已經(jīng)生效。接下來,我們繼續(xù)改進(jìn)polls/models.py,如圖19所示:
關(guān)于datetime模塊、django.utils.timezone模塊想?yún)⒖脊俜轿臋n中的相關(guān)資料。關(guān)于Django中與時區(qū)處理相關(guān)的內(nèi)容也可以參考time zone support doc。
Django提供了豐富的關(guān)鍵字參數(shù)(keyword arguments)驅(qū)動的數(shù)據(jù)庫查看API(a rich database lookup API)。比如,可以執(zhí)行以下命令:
Question.objects.filter(id=1)
Question.objects.filter(question_text__startswith='what')
結(jié)果如圖20 所示:
我們還可以請求(get)今年發(fā)布的問題,執(zhí)行以下命令:
from django.utils import timezone
current_year=timezone.now().year
Question.objects.get(pub_date__year=current_year)
結(jié)果如圖21所示:
當(dāng)你請求(get)一個并不存在的ID時,會得到一個異常,如圖22:
通過主鍵(primary key)進(jìn)行查詢是最常見的形式,Django也提供了利用主鍵進(jìn)行請求(get)的方法:
Question.objects.get(pk=1)
在這里,該命令與Question.objects.get(id=1)等價,其執(zhí)行結(jié)果如圖23:
接下來,我們來確認(rèn)在圖19中所做的改進(jìn)生效與否:
q=Question.objects.get(pk=1)
q.was_published_recently()
執(zhí)行結(jié)果如圖24所示:
我們來關(guān)注Choice模型,并將會為問題(Question)提供一系列的選擇(Choice),Question和Choice通過外鍵(foreign key)建立關(guān)聯(lián)。首先執(zhí)行以下命令:
q=Question.objects.get(pk=1)
q.choice_set.all()
結(jié)果如圖25所示,選擇集顯示為空(Display any choices from the related object set --none so far):
我們新建三個選擇,分別執(zhí)行以下命令:
q.choice_set.create(choice_text='Not much',votes=0)
q.choice_set.create(choice_text='The sky',votes=0)
c=q.choice_set.create(choice_text='Just hacking again',votes=0)
結(jié)果,如圖26所示:
Choice對象也可以通過API連接(access)到相關(guān)的Question對象。執(zhí)行下列命令:
c.question
結(jié)果如圖27:
反之亦然,如前所述,由Question對象也可以通過API連接到Choice對象,執(zhí)行命令:
q.choice_set.all()
q.choice_set.count()
結(jié)果如圖28:
同時,要注意到雙下劃線的使用,我們在前文已經(jīng)使用過,如下例:
Choice.objects.filter(question__pub_date__year=current_year)
運行結(jié)果如圖29:
我們也可以使用delete()執(zhí)行刪除操作:
c=q.choice_set.filter(choice_text__startswith='Just hacking')
c.delete()
關(guān)于模型關(guān)系(model relations)的更多信息,可以參考“Accessing related objects”。關(guān)于API中雙下劃線的使用,可以參考“Field lookups”。關(guān)于數(shù)據(jù)庫API的詳細(xì)信息,可以參考“Database API reference”。