Django簡易教程之一(models)

說明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()"

圖 1

如果系統(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的目錄下。

圖2

如果沒有使用SQLite作為數(shù)據(jù)庫,那么還需要設(shè)置USERPASSWORD以及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所示。

圖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

你將在命令行中看到一下輸出:

圖4

可以看到,你已經(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所示。

圖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):QuestionChoice。其中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ù),比如在本例中將votesdefault值設(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)QuestionChoice對象創(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所示:

圖6

現(xiàn)在,Django已經(jīng)知道我們安裝了'polls'應(yīng)用。下面執(zhí)行以下命令:

$ python manage.py makemigrations polls

應(yīng)該可以得到以下顯示,如圖7所示:

圖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所示:

圖8

下面給出一個可讀的格式,如圖9所示:

圖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所示:

圖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所示:

圖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中的QuestionChoice 類。

from polls.models import Question, Choice ?#import the model classes we just wrote

可以看到系統(tǒng)中目前并沒有問題(question)存在,如圖12所示:

圖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

注13:根據(jù)后臺使用的數(shù)據(jù)庫的不同,結(jié)果可能顯示1亦可能顯示1L。本例中使用的數(shù)據(jù)庫為SQLite。

我們還可以通過python命令查看模型字段中的其他值(access model field values):

q.question_text

q.pub_date

結(jié)果如圖14所示:

圖14

也可以在shell中改變相關(guān)參數(shù)的值,同時不要忘記保存進(jìn)數(shù)據(jù)庫:

q.question_text="what is up?"

q.save()

結(jié)果如圖15所示:

圖15

下面我們再次通過objects.all()來查看數(shù)據(jù)庫中所有已存在的問題(question),執(zhí)行下列命令:

Question.objects.all()

得到如下結(jié)果如圖16:

圖16

可以看到Question.objects.all()命令返回的信息對我們的幫助不大。我們可以通過修改polls/models.py中的QuestionChoice模型來解決這個問題。具體說來就是在Question和Choice類中添加__unicode__函數(shù),如圖17所示:

圖17

注14:本文中采用python 2.7,如果使用Python 3,請使用__str__()函數(shù),具體信息可參考英文原文。

在models.py中添加__unicode__()不僅可以在交互shell界面中為程序員提供方便的信息,也在Django自動生成的后臺管理時具有重要作用。

重新開啟一個Python shell,確認(rèn)我們的修改時候生效,如圖18所示:

圖18

可以看到,我們在polls/models.py中的修改已經(jīng)生效。接下來,我們繼續(xù)改進(jìn)polls/models.py,如圖19所示:

圖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 所示:

圖20

我們還可以請求(get)今年發(fā)布的問題,執(zhí)行以下命令:

from django.utils import timezone

current_year=timezone.now().year

Question.objects.get(pub_date__year=current_year)

結(jié)果如圖21所示:

圖21

當(dāng)你請求(get)一個并不存在的ID時,會得到一個異常,如圖22:

圖22

通過主鍵(primary key)進(jìn)行查詢是最常見的形式,Django也提供了利用主鍵進(jìn)行請求(get)的方法:

Question.objects.get(pk=1)

在這里,該命令與Question.objects.get(id=1)等價,其執(zhí)行結(jié)果如圖23:

圖23

接下來,我們來確認(rèn)在圖19中所做的改進(jìn)生效與否:

q=Question.objects.get(pk=1)

q.was_published_recently()

執(zhí)行結(jié)果如圖24所示:

圖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):

圖25

我們新建三個選擇,分別執(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所示:

圖26,注意最后一行應(yīng)為votes=0

Choice對象也可以通過API連接(access)到相關(guān)的Question對象。執(zhí)行下列命令:

c.question

結(jié)果如圖27:

圖27

反之亦然,如前所述,由Question對象也可以通過API連接到Choice對象,執(zhí)行命令:

q.choice_set.all()

q.choice_set.count()

結(jié)果如圖28:

圖28

同時,要注意到雙下劃線的使用,我們在前文已經(jīng)使用過,如下例:

Choice.objects.filter(question__pub_date__year=current_year)

運行結(jié)果如圖29:

圖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”。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容