91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

基于Django3.0的web框架詳細架構過程是怎么樣的

發布時間:2021-12-08 16:17:52 來源:億速云 閱讀:166 作者:柒染 欄目:網絡管理

這篇文章給大家介紹基于Django3.0的web框架詳細架構過程是怎么樣的,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

下面將進行兩種版本的對比并且匹配版本更迭導致的代碼報錯問題。

Django入門

當今的網站實際上都是富應用程序(rich application),就像成熟的桌面應用程序一樣。Python提供了一組開發Web應用程序的卓越工具。在本文章中,你將學習如何使用Django(http://djangoproject.com/)來開發一個名為“學習筆記”(Learning Log)的項目,這是一個在線日志系統,讓你能夠記錄所學習的有關特定主題的知識。

我們將為這個項目制定規范,然后為應用程序使用的數據定義模型。我們將使用Django的管理系統來輸入一些初始數據,再學習編寫視圖和模板,讓Django能夠為我們的網站創建網頁。Django是一個Web框架——一套用于幫助開發交互式網站的工具。Django能夠響應網頁請求,還能讓你更輕松地讀寫數據庫、管理用戶等。在第19章和第20章,我們將改進“學習筆記”項目,再將其部署到活動的服務器,讓你和你的朋友能夠使用它。

一、建立項目

建立項目時,首先需要以規范的方式對項目進行描述,再建立虛擬環境,以便在其中創建項目。

(一)制定規范

完整的規范詳細說明了項目的目標,闡述了項目的功能,并討論了項目的外觀和用戶界面。與任何良好的項目規劃和商業計劃書一樣,規范應突出重點,幫助避免項目偏離軌道。這里不會制定完整的項目規劃,而只列出一些明確的目標,以突出開發的重點。我們制定的規范如下:

我們要編寫一個名為“學習筆記”的Web應用程序,讓用戶能夠記錄感興趣的主題,并在學習每個主題的過程中添加日志條目。“學習筆記”的主頁對這個網站進行描述,并邀請用戶注冊或登錄。用戶登錄后,就可創建新主題、添加新條目以及閱讀既有的條目。學習新的主題時,記錄學到的知識可幫助跟蹤和復習這些知識。優秀的應用程序讓這個記錄過程簡單易行。

(二)建立虛擬環境

要使用Django,首先需要建立一個虛擬工作環境。虛擬環境是系統的一個位置,你可以在其中安裝包,并將其與其他Python包隔離。將項目的庫與其他項目分離是有益的,且為了在第20章將“學習筆記”部署到服務器,這也是必須的。

為項目新建一個目錄,將其命名為learning_log,再在終端中切換到這個目錄,并創建一個虛擬環境。如果你使用的是Python3,可使用如下命令來創建虛擬環境:

基于Django3.0的web框架詳細架構過程是怎么樣的

這里運行了模塊venv,并使用它來創建一個名為ll_env的虛擬環境。如果這樣做管用,請跳到后面的18.1.4節;如果不管用,請閱讀18.1.3節。

(三)安裝virtualenv

如果你使用的是較早的Python版本,或者系統沒有正確地設置,不能使用模塊venv,可安裝virtualenv包。為此,可執行如下命令:

pip3 install --user virtualenv

別忘了,對于這個命令,你可能需要使用稍微不同的版本(如果你沒有使用過pip,請參閱12.2.1節)。

注意 如果你使用的是Linux系統,且上面的做法不管用,可使用系統的包管理器來安裝virtualenv。例如,要在Ubuntu系統中安裝virtualenv,可使用命令sudo apt-getinstall python-virtualenv。

在終端中切換到目錄learning_log,并像下面這樣創建一個虛擬環境:

基于Django3.0的web框架詳細架構過程是怎么樣的

注意 如果你的系統安裝了多個Python版本,需要指定virtualenv使用的版本。例如,命令virtualenv ll_env --python=python3創建一個使用Python 3的虛擬環境。

win10可用

python3 -m virtualenv 11_env

來創建

(四)激活虛擬環境

建立虛擬環境后,需要使用下面的命令激活它:

基于Django3.0的web框架詳細架構過程是怎么樣的

這個命令運行ll_env/bin中的腳本activate。環境處于活動狀態時,環境名將包含在括號內,如?處所示。在這種情況下,你可以在環境中安裝包,并使用已安裝的包。你在ll_env中安裝的包僅在該環境處于活動狀態時才可用。

注意 如果你使用的是Windows系統,請使用命令ll_env\Scripts\activate(不包含source)來激活這個虛擬環境。

若報錯請使用完整的路徑

E:\科技創新項目\djange框架\learning_log\11_env\Scripts\activate

基于Django3.0的web框架詳細架構過程是怎么樣的

要停止使用虛擬環境,可執行命令deactivate:

E:\科技創新項目\djange框架\learning_log\11_env\Scripts\deactivate

基于Django3.0的web框架詳細架構過程是怎么樣的

如果關閉運行虛擬環境的終端,虛擬環境也將不再處于活動狀態。

(五)安裝Django

創建并激活虛擬環境后,就可安裝Django了:

基于Django3.0的web框架詳細架構過程是怎么樣的

由于我們是在虛擬環境中工作,因此在所有的系統中,安裝Django的命令都相同:不需要指定標志--user,也無需使用python -m pip install package_name這樣較長的命令。

別忘了,Django僅在虛擬環境處于活動狀態時才可用。

(六)在Django中創建項目

在依然處于活動的虛擬環境的情況下(ll_env包含在括號內),執行如下命令來新建一個項目:

django-admin startproject learning_log .

該處的命令讓Django新建一個名為learning_log的項目。這個命令末尾的句點讓新項目使用合適的目錄結構,這樣開發完成后可輕松地將應用程序部署到服務器。

注意 千萬別忘了這個句點,否則部署應用程序時將遭遇一些配置問題。如果忘記了這個句點,就將創建的文件和文件夾刪除(ll_env除外),再重新運行這個命令。

基于Django3.0的web框架詳細架構過程是怎么樣的

注意windows下ls指令無法使用,要用dir查看目錄下所有文件

基于Django3.0的web框架詳細架構過程是怎么樣的

該處運行了命令ls(在Windows系統上應為dir),結果表明Django新建了一個名為learning_log的目錄。它還創建了一個名為manage.py的文件,這是一個簡單的程序,它接受命令并將其交給Django的相關部分去運行。我們將使用這些命令來管理諸如使用數據庫和運行服務器等任務。

目錄learning_log包含4個文件(見上),其中最重要的是settings.py、urls.py和wsgi.py。文件settings.py指定Django如何與你的系統交互以及如何管理項目。在開發項目的過程中,我們將修改其中一些設置,并添加一些設置。文件urls.py告訴Django應創建哪些網頁來響應瀏覽器請求。文件wsgi.py幫助Django提供它創建的文件,這個文件名是web server gatewayinterface(Web服務器網關接口)的首字母縮寫。

(七)創建數據庫

Django將大部分與項目相關的信息都存儲在數據庫中,因此我們需要創建一個供Django使用的數據庫。為給項目“學習筆記”創建數據庫,請在處于活動虛擬環境中的情況下執行下面的命令:

python3 manage.py migrate

下圖中的該處Django指出它將創建必要的數據庫表,用于存儲我們將在這個項目(Synchronizeunmigrated apps,同步未遷移的應用程序)中使用的信息,再確保數據庫結構與當前代碼(Apply all migrations,應用所有的遷移)匹配。

基于Django3.0的web框架詳細架構過程是怎么樣的

我們將修改數據庫稱為遷移數據庫。首次執行命令migrate時,將讓Django確保數據庫與項目的當前狀態匹配。在使用SQLite(后面將更詳細地介紹)的新項目中首次執行這個命令時,Django將新建一個數據庫。

上圖中的命令中,Django指出它將創建必要的數據庫表,用于存儲我們將在這個項目(Synchronizeunmigrated apps,同步未遷移的應用程序)中使用的信息,再確保數據庫結構與當前代碼(Apply all migrations,應用所有的遷移)匹配。

接著,我們運行了命令dir,其輸出表明Django又創建了一個文件——db.sqlite3。SQLite是一種使用單個文件的數據庫,是編寫簡單應用程序的理想選擇,因為它讓你不用太關注數據庫管理的問題。

(八)查看項目

下面來核實Django是否正確地創建了項目。為此,可執行命令runserver,如下所示:

python3 manage.py runserver

基于Django3.0的web框架詳細架構過程是怎么樣的

Django啟動一個服務器,讓你能夠查看系統中的項目,了解它們的工作情況。當你在瀏覽器中輸入URL以請求網頁時,該Django服務器將進行響應:生成合適的網頁,并將其發送給瀏覽器。

在?處,Django通過檢查確認正確地創建了項目;在?處,它指出了使用的Django版本以及當前使用的設置文件的名稱;在?處,它指出了項目的URL。URL http://127.0.0.1:8000/表明項目將在你的計算機(即localhost)的端口8000上偵聽請求。localhost是一種只處理當前系統發出的請求,而不允許其他任何人查看你正在開發的網頁的服務器。

現在打開一款Web瀏覽器,并輸入URL:http://localhost:8000/;如果這不管用,請輸入http://127.0.0.1:8000/。你將看到類似于下圖所示的頁面,這個頁面是Django創建的,讓你知道到目前為止一切正常。現在暫時不要關閉這個服務器。若要關閉這個服務器,按Ctrl+C即可。

基于Django3.0的web框架詳細架構過程是怎么樣的

注意 如果出現錯誤消息“That port is already in use”(指定端口已被占用),請執行命令python manage.pyrunserver 8001,讓Diango使用另一個端口;如果這個端口也不可用,請不斷執行上述命令,并逐漸增大其中的端口號,直到找到可用的端口。

動手試一試

18-1 新項目:

為更深入地了解Django做了些什么,可創建兩個空項目,看看Django創建了什么。新建一個文件夾,并給它指定簡單的名稱,如InstaBook或FaceGram(不要在目錄learning_log中新建該文件夾),在終端中切換到該文件夾,并創建一個虛擬環境。在這個虛擬環境中安裝Django,并執行命令django-admin.py startprojectinstabook.(千萬不要忘了這個命令末尾的句點)。

看看這個命令創建了哪些文件和文件夾,并與項目“學習筆記”包含的文件和文件夾進行比較。這樣多做幾次,直到對Django新建項目時創建的東西了如指掌。然后,將項目目錄刪除——如果你想這樣做的話。

二、創建應用程序

Django項目由一系列應用程序組成,它們協同工作,讓項目成為一個整體。我們暫時只創建一個應用程序,它將完成項目的大部分工作。在第19章,我們將再添加一個管理用戶賬戶的應用程序。

當前,在前面打開的終端窗口中應該還運行著runserver。請再打開一個終端窗口(或標簽頁),并切換到manage.py所在的目錄。激活該虛擬環境,再執行命令startapp:

python3 manage.py startapp learning_logs

基于Django3.0的web框架詳細架構過程是怎么樣的

命令startapp appname讓Django建立創建應用程序所需的基礎設施。

如果現在查看項目目錄,將看到其中新增了一個文件夾learning_logs(見?)。打開這個文件夾,看看Django都創建了什么(見?)。其中最重要的文件是models.py、admin.py和views.py。我們將使用models.py來定義我們要在應用程序中管理的數據。admin.py和views.py將在稍后介紹。

(一)定義模型

我們來想想涉及的數據。每位用戶都需要在學習筆記中創建很多主題。用戶輸入的每個條目都與特定主題相關聯,這些條目將以文本的方式顯示。我們還需要存儲每個條目的時間戳,以便能夠告訴用戶各個條目都是什么時候創建的。

打開文件models.py,看看它當前包含哪些內容:

models.py

基于Django3.0的web框架詳細架構過程是怎么樣的

這為我們導入了模塊models,還讓我們創建自己的模型。模型告訴Django如何處理應用程序中存儲的數據。在代碼層面,模型就是一個類,就像前面討論的每個類一樣,包含屬性和方法。下面是表示用戶將要存儲的主題的模型:

from django.db import models

# Create your models here.
class Topic(models.Model):
	"""用戶學習的主題"""
	text = models.CharField(max_length=200)
	date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
	"""返回模型的字符串表示"""
	return self.text

基于Django3.0的web框架詳細架構過程是怎么樣的

我們創建了一個名為Topic的類,它繼承了Model——Django中一個定義了模型基本功能的類。Topic類只有兩個屬性:text和date_added。屬性text是一個CharField——由字符或文本組成的數據(見?)。需要存儲少量的文本,如名稱、標題或城市時,可使用CharField。定義CharField屬性時,必須告訴Django該在數據庫中預留多少空間。在這里,我們將max_length設置成了200(即200個字符),這對存儲大多數主題名來說足夠了。

屬性date_added是一個DateTimeField——記錄日期和時間的數據(見?)。我們傳遞了實參auto_now_add=True,每當用戶創建新主題時,這都讓Django將這個屬性自動設置成當前日期和時間。

注意 要獲悉可在模型中使用的各種字段,請參閱DjangoModel Field Reference(Django模型字段參考),其網址為https://docs.djangoproject.com/en/1.8/ref/models/fields/。就當前而言,你無需全面了解其中的所有內容,但自己開發應用程序時,這些內容會提供極大的幫助。

我們需要告訴Django,默認應使用哪個屬性來顯示有關主題的信息。Django調用方法__str__()來顯示模型的簡單表示。在這里,我們編寫了方法__str__(),它返回存儲在屬性text中的字符串(見?)。

注意 如果你使用的是Python 2.7,應調用方法__unicode__(),而不是__str__(),但其中的代碼相同。

(二)激活模型

要使用模型,必須讓Django將應用程序包含到項目中。為此,打開settings.py(它位于目錄learning_log/learning_log中),你將看到一個這樣的片段,即告訴Django哪些應用程序安裝在項目中:

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

基于Django3.0的web框架詳細架構過程是怎么樣的

這是一個元組,告訴Django項目是由哪些應用程序組成的。請將INSTALLED_APPS修改成下面這樣,將前面的應用程序添加到這個元組中:

基于Django3.0的web框架詳細架構過程是怎么樣的

INSTALLED_APPS = [
	--snip-- #省略上面代碼
    'django.contrib.staticfiles',
    #我的應用程序
    'learning_logs',
]

通過將應用程序編組,在項目不斷增大,包含更多的應用程序時,有助于對應用程序進行跟蹤。這里新建了一個名為Myapps的片段,當前它只包含應用程序learning_logs。接下來,需要讓Django修改數據庫,使其能夠存儲與模型Topic相關的信息。為此,在終端窗口中執行下面的命令:

python3 manage.py makemigrations learning_logs

注意:

如果出現

LookupError: No installed app with label 'admin'.

的報錯,則說明是上面的settings.py文件設置格式出現錯誤

基于Django3.0的web框架詳細架構過程是怎么樣的

命令makemigrations讓Django確定該如何修改數據庫,使其能夠存儲與我們定義的新模型相關聯的數據。輸出表明Django創建了一個名為0001_initial.py的遷移文件,這個文件將在數據庫中為模型Topic創建一個表。

下面來應用這種遷移,讓Django替我們修改數據庫:

python3 manage.py migrate

基于Django3.0的web框架詳細架構過程是怎么樣的

這個命令的大部分輸出都與我們首次執行命令migrate的輸出相同。我們需要檢查的是?處的輸出行,在這里,Django確認為learning_logs應用遷移時一切正常(OK)。

每當需要修改“學習筆記”管理的數據時,都采取如下三個步驟:修改models.py;對learning_logs調用makemigrations;讓Django遷移項目。

(三)Django管理網站

為應用程序定義模型時,Django提供的管理網站(adminsite)讓你能夠輕松地處理模型。網站的管理員可使用管理網站,但普通用戶不能使用。在本節中,我們將建立管理網站,并通過它使用模型Topic來添加一些主題。

1.創建超級用戶

Django允許你創建具備所有權限的用戶——超級用戶。權限決定了用戶可執行的操作。最嚴格的權限設置只允許用戶閱讀網站的公開的信息;注冊了的用戶通常可閱讀自己的私有數據,還可查看一些只有會員才能查看的信息。為有效地管理Web應用程序,網站所有者通常需要訪問網站存儲的所有信息。優秀的管理員會小心對待用戶的敏感信息,因為用戶對其訪問的應用程序有極大的信任。

為在Django中創建超級用戶,請執行下面的命令并按提示做:

python3 manage.py createsuperuser

基于Django3.0的web框架詳細架構過程是怎么樣的

你執行命令createsuperuser時,Django提示你輸入超級用戶的用戶名(見?)。這里我們輸入的是ll_admin,但你可以輸入任何用戶名,比如電子郵件地址,也可讓這個字段為空(見?)。你需要輸入密碼兩次(見?)。

注意 可能會對網站管理員隱藏有些敏感信息。例如,Django并不存儲你輸入的密碼,而存儲從該密碼派生出來的一個字符串——散列值。每當你輸入密碼時,Django都計算其散列值,并將結果與存儲的散列值進行比較。如果這兩個散列值相同,就通過了身份驗證。通過存儲散列值,即便黑客獲得了網站數據庫的訪問權,也只能獲取其中存儲的散列值,而無法獲得密碼。在網站配置正確的情況下,幾乎無法根據散列值推導出原始密碼。

2.向管理網站注冊模型

Django自動在管理網站中添加了一些模型,如User和Group,但對于我們創建的模型,必須手工進行注冊。

我們創建應用程序learning_logs時,Django在models.py所在的目錄中創建了一個名為admin.py的文件:

admin.py

from django.contrib import admin

# Register your models here.
from learning_logs.models import Topic
admin.site.register(Topic)

基于Django3.0的web框架詳細架構過程是怎么樣的

這些代碼導入我們要注冊的模型Topic(見?),再使用admin.site.register()(見?)讓Django通過管理網站管理我們的模型。

現在,使用超級用戶賬戶訪問管理網站:訪問http://localhost:8000/admin/,并輸入你剛創建的超級用戶的用戶名和密碼,你將看到類似于下圖所示的屏幕。這個網頁讓你能夠添加和修改用戶和用戶組,還可以管理與剛才定義的模型Topic相關的數據。

基于Django3.0的web框架詳細架構過程是怎么樣的

注意 如果你在瀏覽器中看到一條消息,指出訪問的網頁不可用,請確認你在終端窗口中運行著Django服務器。如果沒有,請激活虛擬環境,并執行命令python manage.py runserver。

3.添加主題

向管理網站注冊Topic后,我們來添加第一個主題。為此,單擊Topics進入主題網頁,它幾乎是空的,這是因為我們還沒有添加任何主題。單擊Add,你將看到一個用于添加新主題的表單。在第一個方框中輸入Chess,再單擊Save,這將返回到主題管理頁面,其中包含剛創建的主題。下面再創建一個主題,以便有更多的數據可供使用。再次單擊Add,并創建另一個主題Rock Climbing。當你單擊Save時,將重新回到主題管理頁面,其中包含主題Chess和RockClimbing。

(四)定義模型Entry

要記錄學到的國際象棋和攀巖知識,需要為用戶可在學習筆記中添加的條目定義模型。每個條目都與特定主題相關聯,這種關系被稱為多對一關系,即多個條目可關聯到同一個主題。

下面是模型Entry的代碼:

models.py

from django.db import models
class Topic(models. Model) :
	--snip--
class Entry(models.Model):?
	"""學到的有關某個主題的具體知識"""
	topic = models.ForeignKey(Topic)?
	text = models.TextField()?
	date_added = models.DateTimeField(auto_now_add=True)
	class Meta: ?
		verbose_name_plural = 'entries'
	def __str__(self) :
		"""返回模型的字符串表示"""
		return self.text[:50]+"..."?

像Topic一樣,Entry也繼承了Django基類Model(見?)。第一個屬性topic是一個ForeignKey實例(見?)。外鍵是一個數據庫術語,它引用了數據庫中的另一條記錄;這些代碼將每個條目關聯到特定的主題。每個主題創建時,都給它分配了一個鍵(或ID)。需要在兩項數據之間建立聯系時,Django使用與每項信息相關聯的鍵。稍后我們將根據這些聯系獲取與特定主題相關聯的所有條目。

接下來是屬性text,它是一個TextField實例(見?)。這種字段不需要長度限制,因為我們不想限制條目的長度。屬性date_added讓我們能夠按創建順序呈現條目,并在每個條目旁邊放置時間戳。

在?處,我們在Entry類中嵌套了Meta類。Meta存儲用于管理模型的額外信息,在這里,它讓我們能夠設置一個特殊屬性,讓Django在需要時使用Entries來表示多個條目。如果沒有這個類, Django將使用Entrys來表示多個條目。最后,方法__str__()告訴Django,呈現條目時應顯示哪些信息。由于條目包含的文本可能很長,我們讓Django只顯示text的前50個字符(見?)。我們還添加了一個省略號,指出顯示的并非整個條目。

(五)遷移模型Entry

由于我們添加了一個新模型,因此需要再次遷移數據庫。你將慢慢地對這個過程了如指掌:

修改models.py,執行命令

python manage.py makemigrations app_name

出現報錯

TypeError: __init__() missing 1 required positional argument: 'on_delete'

解決方案:
定義外鍵的時候需要加上 on_delete=;
即:contract = models.ForeignKey(Contract, on_delete=models.CASCADE)

原因如下:
django 升級到2.0之后,表與表之間關聯的時候,必須要寫on_delete參數,否則會報異常:
TypeError: init() missing 1 required positional argument: ‘on_delete’

on_delete各個參數的含義如下:

on_delete=None, # 刪除關聯表中的數據時,當前表與其關聯的field的行為
on_delete=models.CASCADE, # 刪除關聯數據,與之關聯也刪除
on_delete=models.DO_NOTHING, # 刪除關聯數據,什么也不做
on_delete=models.PROTECT, # 刪除關聯數據,引發錯誤ProtectedError
# models.ForeignKey('關聯表', on_delete=models.SET_NULL, blank=True, null=True)
on_delete=models.SET_NULL, # 刪除關聯數據,與之關聯的值設置為null(前提FK字段需要設置為可空,一對一同理)
# models.ForeignKey('關聯表', on_delete=models.SET_DEFAULT, default='默認值')
on_delete=models.SET_DEFAULT, # 刪除關聯數據,與之關聯的值設置為默認值(前提FK字段需要設置默認值,一對一同理)
on_delete=models.SET, # 刪除關聯數據,
a. 與之關聯的值設置為指定值,設置:models.SET(值)
b. 與之關聯的值設置為可執行對象的返回值,設置:models.SET(可執行對象)

基于Django3.0的web框架詳細架構過程是怎么樣的

修改后,再執行命令成功

python3 manage.py migrate

下面來遷移數據庫并查看輸出:

基于Django3.0的web框架詳細架構過程是怎么樣的

生成了一個新的遷移文件——0002_entry.py,它告訴Django如何修改數據庫,使其能夠存儲與模型Entry相關的信息(見?)。執行命令migrate,我們發現Django應用了這種遷移且一切順利(見?)。

(六)向管理網站注冊Entry

我們還需要注冊模型Entry。為此,需要將admin.py修改成類似于下面這樣:

from django.contrib import admin
from learning_logs.models import Topic,Entry
admin.site.register(Topic)
admin.site.register(Entry)

返回到http://localhost:8000/admin/,你將看到learning_logs下列出了Entries。單擊Entries的Add鏈接,或者單擊Entries再選擇Add entry。你將看到一個下拉列表,讓你能夠選擇要為哪個主題創建條目,還有一個用于輸入條目的文本框。從下拉列表中選擇Chess,并添加一個條目。下面是我添加的第一個條目。

The opening is the first part of the game, roughly thefirst ten moves or so. In the opening, it's a good ideato do three things— bring out your bishops andknights, try to control the center of the board, andcastle your king.(國際象棋的第一個階段是開局,大致是前10步左右。在開局階段,最好做三件事情:將象和馬調出來;努力控制棋盤的中間區域;用車將王護住。)Of course, these are just guidelines. It will beimportant to learn when to follow these guidelinesand when to disregard these suggestions.(當然,這些只是指導原則。學習什么情況下遵守這些原則、什么情況下不用遵守很重要。)

當你單擊Save時,將返回到主條目管理頁面。在這里,你將發現使用text[:50]作為條目的字符串表示的好處:管理界面中,只顯示了條目的開頭部分而不是其所有文本,這使得管理多個條目容易得多。

再來創建一個國際象棋條目,并創建一個攀巖條目,以提供一些初始數據。下面是第二個國際象棋條目。

In the opening phase of the game, it's important tobring out your bishops and knights. These pieces arepowerful and maneuverable enough to play asignificant role in the beginning moves of a game.(在國際象棋的開局階段,將象和馬調出來很重要。這些棋子威力大,機動性強,在開局階段扮演著重要角色。)

下面是第一個攀巖條目:

One of the most important concepts in climbing is tokeep your weight on your feet as much as possible.There's a myth that climbers can hang all day on theirarms. In reality, good climbers have practiced specificways of keeping their weight over their feet wheneverpossible.(最重要的攀巖概念之一是盡可能讓雙腳承受體重。有謬誤認為攀巖者能依靠手臂的力量堅持一整天。實際上,優秀的攀巖者都經過專門訓練,能夠盡可能讓雙腳承受體重。)

繼續往下開發“學習筆記”時,這三個條目可為我們提供使用的數據。

(七)Django shell

輸入一些數據后,就可通過交互式終端會話以編程方式查看這些數據了。這種交互式環境稱為Django shell,是測試項目和排除其故障的理想之地。下面是一個交互式shell會話示例:

python3 manage.py shell
from learning_logs.models import Topic

Topic.objects.all()

基于Django3.0的web框架詳細架構過程是怎么樣的

在活動的虛擬環境中執行時,命令python manage.py shell啟動一個Python解釋器,可使用它來探索存儲在項目數據庫中的數據。在這里,我們導入了模塊learning_logs.models中的模型Topic(見?),然后使用方法Topic.objects.all()來獲取模型Topic的所有實例;它返回的是一個列表,稱為查詢集(queryset)。

我們可以像遍歷列表一樣遍歷查詢集。下面演示了如何查看分配給每個主題對象的ID:

topics = Topic.objects.all()
for topic in topics:
	print(topic.id,topic)

基于Django3.0的web框架詳細架構過程是怎么樣的

我們將返回的查詢集存儲在topics中,然后打印每個主題的id屬性和字符串表示。從輸出可知,主題Chess的ID為1,而RockClimbing的ID為2。

知道對象的ID后,就可獲取該對象并查看其任何屬性。下面來看看主題Chess的屬性text和date_added的值:

t = Topic.objects.get(id=1)
t.text
t.date_added

基于Django3.0的web框架詳細架構過程是怎么樣的

我們還可以查看與主題相關聯的條目。前面我們給模型Entry定義了屬性topic,這是一個ForeignKey,將條目與主題關聯起來。利用這種關聯,Django能夠獲取與特定主題相關聯的所有條目,如下所示:

t.entry_set.all()

基于Django3.0的web框架詳細架構過程是怎么樣的

為通過外鍵關系獲取數據,可使用相關模型的小寫名稱、下劃線和單詞set(見?)。例如,假設你有模型Pizza和Topping,而Topping通過一個外鍵關聯到Pizza;如果你有一個名為my_pizza的對象,表示一張比薩,就可使用代碼my_pizza.topping_set.all()來獲取這張比薩的所有配料。

編寫用戶可請求的網頁時,我們將使用這種語法。確認代碼能獲取所需的數據時,shell很有幫助。如果代碼在shell中的行為符合預期,那么它們在項目文件中也能正確地工作。如果代碼引發了錯誤或獲取的數據不符合預期,那么在簡單的shell環境中排除故障要比在生成網頁的文件中排除故障容易得多。我們不會太多地使用shell,但應繼續使用它來熟悉對存儲在項目中的數據進行訪問的Django語法。

注意 每次修改模型后,你都需要重啟shell,這樣才能看到修改的效果。要退出shell會話,可按Ctr+D;如果你使用的是Windows系統,應按Ctr+Z,再按回車鍵。

動手試一試

18-2 簡短的條目:

當前,Django在管理網站或shell中顯示Entry實例時,模型Entry的方法__str__()都在它的末尾加上省略號。請在方法__str__()中添加一條if語句,以便僅在條目長度超過50字符時才添加省略號。使用管理網站來添加一個長度少于50字符的條目,并核實顯示它時沒有省略號。

18-3 Django API:

編寫訪問項目中的數據的代碼時,你編寫的是查詢。請瀏覽有關如何查詢數據的文檔,其網址為https://docs.djangoproject.com/en/7.8/topics/db/queries/。其中大部分內容都是你不熟悉的,但等你自己開發項目時,這些內容會很有用。

18-4 比薩店:

新建一個名為pizzeria的項目,并在其中添加一個名為pizzas的應用程序。定義一個名為Pizza的模型,它包含字段name,用于存儲比薩名稱,如Hawaiian和Meat Lovers。定義一個名為Topping的模型,它包含字段pizza和name,其中字段pizza是一個關聯到Pizza的外鍵,而字段name用于存儲配料,如pineapple、Canadianbacon和sausage。

向管理網站注冊這兩個模型,并使用管理網站輸入一些比薩名和配料。使用shell來查看你輸入的數據。

三、創建網頁:

學習筆記主頁使用Django創建網頁的過程通常分三個階段:定義URL、編寫視圖和編寫模板。首先,你必須定義URL模式。URL模式描述了URL是如何設計的,讓Django知道如何將瀏覽器請求與網站URL匹配,以確定返回哪個網頁。

每個URL都被映射到特定的視圖——視圖函數獲取并處理網頁所需的數據。視圖函數通常調用一個模板,后者生成瀏覽器能夠理解的網頁。為明白其中的工作原理,我們來創建學習筆記的主頁。我們將定義該主頁的URL、編寫其視圖函數并創建一個簡單的模板。

鑒于我們只是要確保“學習筆記”按要求的那樣工作,我們將暫時讓這個網頁盡可能簡單。Web應用程序能夠正常運行后,設置樣式可使其更有趣,但中看不中用的應用程序毫無意義。就目前而言,主頁只顯示標題和簡單的描述。

(一)映射URL

用戶通過在瀏覽器中輸入URL以及單擊鏈接來請求網頁,因此我們需要確定項目需要哪些URL。主頁的URL最重要,它是用戶用來訪問項目的基礎URL。當前,基礎URL(http://localhost:8000/)返回默認的Django網站,讓我們知道正確地建立了項目。我們將修改這一點,將這個基礎URL映射到“學習筆記”的主頁。

打開項目主文件夾learning_log中的文件urls.py,你將看到如下代碼:

from django.contrib import admin?
from django.urls import path

urlpatterns = [?
    path('admin/', admin.site.urls),?
]

前兩行導入了為項目和管理網站管理URL的函數和模塊(見?)。這個文件的主體定義了變量urlpatterns(見?)。在這個針對整個項目的urls.py文件中,變量urlpatterns包含項目中的應用程序的URL。?處的代碼包含模塊admin.site.urls,該模塊定義了可在管理網站中請求的所有URL。

我們需要包含learning_logs的URL:

原有代碼

from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]

修改后

from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
	url(r'^admin/',include(admin.site.urls)),
	url (r'', include('learning_logs.urls',namespace='learning_logs')),?
]

在?處,我們添加了一行代碼來包含模塊learning_logs.urls。這行代碼包含實參namespace,讓我們能夠將learning_logs的URL同項目中的其他URL區分開來,這在項目開始擴展時很有幫助。

默認的urls.py包含在文件夾learning_log中,現在我們需要在文件夾learning_logs中創建另一個urls.py文件:

"""定義learning_ logs的URL模式"""?
from django.conf.urls import url?
from . import views?
urlpatterns = [?
	# 主頁
	url(r'^$', views.index, name='index'),?
]

為弄清楚當前位于哪個urls.py文件中,我們在這個文件開頭添加了一個文檔字符串(見?)。接下來,我們導入了函數url,因為我們需要使用它來將URL映射到視圖(見?)。我們還導入了模塊views(見?),其中的句點讓Python從當前的urls.py模塊所在的文件夾中導入視圖。在這個模塊中,變量urlpatterns是一個列表,包含可在應用程序learning_logs中請求的網頁(見?)。

實際的URL模式是一個對函數url()的調用,這個函數接受三個實參(見?)。第一個是一個正則表達式。Django在urlpatterns中查找與請求的URL字符串匹配的正則表達式,因此正則表達式定義了Django可查找的模式。

我們來看看正則表達式r'^$'。其中的r讓Python將接下來的字符串視為原始字符串,而引號告訴Python正則表達式始于和終于何處。脫字符(^)讓Python查看字符串的開頭,而美元符號讓Python查看字符串的末尾。總體而言,這個正則表達式讓Python查找開頭和末尾之間沒有任何東西的URL。Python忽略項目的基礎URL(http://localhost:8000/),因此這個正則表達式與基礎URL匹配。其他URL都與這個正則表達式不匹配。如果請求的URL不與任何URL模式匹配,Django將返回一個錯誤頁面。

url()的第二個實參(見?)指定了要調用的視圖函數。請求的URL與前述正則表達式匹配時,Django將調用views.index(這個視圖函數將在下一節編寫)。第三個實參將這個URL模式的名稱指定為index,讓我們能夠在代碼的其他地方引用它。每當需要提供到這個主頁的鏈接時,我們都將使用這個名稱,而不編寫URL。

注意:

以上教程為Django1.11

在django2.0后不支持使用在urls.py中寫

url(r'^admin/', include(admin.site.urls))

runserver后會發生報錯

基于Django3.0的web框架詳細架構過程是怎么樣的

,直接用

path('admin/', admin.site.urls)

,
對于應用中自定義urls.py文件的引用還是需要使用include()

百度一下得到改進辦法

首先要修改learning_log\urls.py

from django.contrib import admin
# from django.conf.urls import include, url
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('learning_logs.urls', namespace='learning_logs')),
    # url(r'^admin/', include(admin.site.urls)),
    # url(r'', include('learning_logs.urls', namespace='learning_logs')),Django2.0使用django.urls.path
]

但只加入namespace會報錯,必須在learning_logs\urls.py中定義變量app_name才行

learning_logs\urls.py

from django.urls import path, include, re_path

from . import views

urlpatterns = [
    # url(r'^$', views.index, name='index'),
    re_path('^$', views.index, name='index')
]

app_name = 'learning_logs'

然后再運行runserver就不會出錯了

注意 正則表達式通常被稱為regex,幾乎每種編程語言都使用它。它們的用途多得難以置信,但需要經過一定的練習才能熟悉。如果你不明白前面介紹的內容,也不用擔心,你在完成這個項目的過程中,將會看到很多正則表達式。

(二)編寫視圖

視圖函數接受請求中的信息,準備好生成網頁所需的數據,再將這些數據發送給瀏覽器——這通常是使用定義了網頁是什么樣的模板實現的。

learning_logs中的文件views.py是你執行命令python manage.py startapp時自動生成的,當前其內容如下:

基于Django3.0的web框架詳細架構過程是怎么樣的

當前,這個文件只導入了函數render(),它根據視圖提供的數據渲染響應。下面的代碼演示了該如何為主頁編寫視圖:

from django.shortcuts import render
def index(request):
	"""學習筆記的主頁"""
	return render(request,'learning_logs/index.html')

URL請求與我們剛才定義的模式匹配時,Django將在文件views.py中查找函數index(),再將請求對象傳遞給這個視圖函數。在這里,我們不需要處理任何數據,因此這個函數只包含調用render()的代碼。這里向函數render()提供了兩個實參:原始請求對象以及一個可用于創建網頁的模板。下面來編寫這個模板。

18.3.3 編寫模板

模板定義了網頁的結構。模板指定了網頁是什么樣的,而每當網頁被請求時,Django將填入相關的數據。模板讓你能夠訪問視圖提供的任何數據。我們的主頁視圖沒有提供任何數據,因此相應的模板非常簡單。

在文件夾learning_logs中新建一個文件夾,并將其命名為templates。在文件夾templates中,再新建一個文件夾,并將其命名為learning_logs。這好像有點多余(我們在文件夾learning_logs中創建了文件夾templates,又在這個文件夾中創建了文件夾learning_logs),但建立了Django能夠明確解讀的結構,即便項目很大,包含很多應用程序亦如此。在最里面的文件夾learning_logs中,新建一個文件,并將其命名為index.html,再在這個文件中編寫如下代碼:

<p>Learning Log</p>
<p>Learning Log helps you keep track of your learning, for any topic you're learning about. </p>

這個文件非常簡單。對于不熟悉HTML的讀者,這里解釋一下:

標簽<p></p>標識段落;標簽<p>指出了段落的開頭位置,而標簽</p>指出了段落的結束位置。這里定義了兩個段落:第一個充當標題,第二個闡述了用戶可使用“學習筆記”來做什么。

現在,如果你請求這個項目的基礎URL——http://localhost:8000/,將看到剛才創建的網頁,而不是默認的Django網頁。Django接受請求的URL,發現該URL與模式r'^$'匹配,因此調用函數views.index(),這將使用index.html包含的模板來渲染網頁,結果如下圖所示。

基于Django3.0的web框架詳細架構過程是怎么樣的

創建網頁的過程看起來可能很復雜,但將URL、視圖和模板分離的效果實際上很好。這讓我們能夠分別考慮項目的不同方面,且在項目很大時,讓各個參與者可專注于其最擅長的方面。例如,數據庫專家可專注于模型,程序員可專注于視圖代碼,而Web設計人員可專注于模板。

動手試一試
18-5 膳食規劃程序:

假設你要創建一個應用程序,幫助用戶規劃一周的膳食。為此,新建一個文件夾,并將其命名為meal_planner,再在這個文件夾中新建一個Django項目。接下來,新建一個名為meal_plans的應用程序,并為這個項目創建一個簡單的主頁。

18-6 比薩店主頁:

在你為完成練習18-4而創建的項目Pizzeria中,添加一個主頁。

四、創建其他網頁

制定創建網頁的流程后,可以開始擴充“學習筆記”項目了。我們將創建兩個顯示數據的網頁,其中一個列出所有的主題,另一個顯示特定主題的所有條目。對于每個網頁,我們都將指定URL模式,編寫一個視圖函數,并編寫一個模板。但這樣做之前,我們先創建一個父模板,項目中的其他模板都將繼承它。

(一)模板繼承

創建網站時,幾乎都有一些所有網頁都將包含的元素。在這種情況下,可編寫一個包含通用元素的父模板,并讓每個網頁都繼承這個模板,而不必在每個網頁中重復定義這些通用元素。這種方法能讓你專注于開發每個網頁的獨特方面,還能讓修改項目的整體外觀容易得多。

1.父模板

我們首先來創建一個名為base.html的模板,并將其存儲在index.html所在的目錄中。這個文件包含所有頁面都有的元素;其他的模板都繼承base.html。當前,所有頁面都包含的元素只有頂端的標題。我們將在每個頁面中包含這個模板,因此我們將這個標題設置為到主頁的鏈接:

<p>
<a href=" {% url 'learning_logs:index' %} ">Learning Log</a> ?
</p>
{% block content %} {% endblock content %}?

這個文件的第一部分創建一個包含項目名的段落,該段落也是一個到主頁的鏈接。為創建鏈接,我們使用了一個模板標簽,它是用大括號和百分號({ % % })表示的。模板標簽是一小段代碼,生成要在網頁中顯示的信息。在這個實例中,模板標簽{ % url 'learning_logs:index' % }生成一個URL,該URL與learning_logs/urls.py中定義的名為index的URL模式匹配(見?)。在這個示例中,learning_logs是一個命名空間,而index是該命名空間中一個名稱獨特的URL模式。

在簡單的HTML頁面中,鏈接是使用錨標簽定義的:

<a href="link_url">link text</a>

讓模板標簽來生成URL,可讓鏈接保持最新容易得多。要修改項目中的URL,只需修改urls.py中的URL模式,這樣網頁被請求時,Django將自動插入修改后的URL。在我們的項目中,每個網頁都將繼承base.html,因此從現在開始,每個網頁都包含到主頁的鏈接。

在?處,我們插入了一對塊標簽。這個塊名為content,是一個占位符,其中包含的信息將由子模板指定。

子模板并非必須定義父模板中的每個塊,因此在父模板中,可使用任意多個塊來預留空間,而子模板可根據需要定義相應數量的塊。

注意 在Python代碼中,我們幾乎總是縮進四個空格。相比于Python文件,模板文件的縮進層級更多,因此每個層級通常只縮進兩個空格。

2.子模板

現在需要重新編寫index.html,使其繼承base.html,如下所示:

{% extends "learning_logs/base.html" %}?
{% block content %} ?
  <p>Learning Log helps you keep track of your learning, for any topic you're learning about. </p>
{% endblock content %}?

如果將這些代碼與原來的index.html進行比較,可發現我們將標題Learning Log替換成了從父模板那里繼承的代碼(見?)。子模板的第一行必須包含標簽{ % extends % },讓Django知道它繼承了哪個父模板。文件base.html位于文件夾learning_logs中,因此父模板路徑中包含learning_logs。這行代碼導入模板base.html的所有內容,讓index.html能夠指定要在content塊預留的空間中添加的內容。

在?處,我們插入了一個名為content的{ % block % }標簽,以定義content塊。不是從父模板繼承的內容都包含在content塊中,在這里是一個描述項目“學習筆記”的段落。在?處,我們使用標簽{ % endblock content % }指出了內容定義的結束位置。

模板繼承的優點開始顯現出來了:在子模板中,只需包含當前網頁特有的內容。這不僅簡化了每個模板,還使得網站修改起來容易得多。要修改很多網頁都包含的元素,只需在父模板中修改該元素,你所做的修改將傳導到繼承該父模板的每個頁面。在包含數十乃至數百個網頁的項目中,這種結構使得網站改進起來容易而且快捷得多。

注意 在大型項目中,通常有一個用于整個網站的父模板——base.html,且網站的每個主要部分都有一個父模板。每個部分的父模板都繼承base.html,而網站的每個網頁都繼承相應部分的父模板。這讓你能夠輕松地修改整個網站的外觀、網站任何一部分的外觀以及任何一個網頁的外觀。這種配置提供了一種效率極高的工作方式,讓你樂意不斷地去改進網站。

(二)顯示所有主題的頁面

有了高效的網頁創建方法,就能專注于另外兩個網頁了:顯示全部主題的網頁以及顯示特定主題中條目的網頁。所有主題頁面顯示用戶創建的所有主題,它是第一個需要使用數據的網頁。

1.URL模式

首先,我們來定義顯示所有主題的頁面的URL。通常,使用一個簡單的URL片段來指出網頁顯示的信息;我們將使用單詞topics,因此URLhttp://localhost:8000/topics/將返回顯示所有主題的頁面。下面演示了該如何修改learning_logs/urls.py:

"""定義learning_ logs的URL模式"""
from django.urls import path, include, re_path
from . import views
urlpatterns = [
	# 主頁
    # url(r'^$', views.index, name='index'),
    re_path('^$', views.index, name='index'),

    #url(r'^topics/$',views.topics,name='topics'),
    path('topics/',views.topics,name='topics'),?
]

app_name = 'learning_logs'

我們只是在用于主頁URL的正則表達式中添加了topics/(見?)。Django檢查請求的URL時,這個模式與這樣的URL匹配:基礎URL后面跟著topics。可以在末尾包含斜杠,也可以省略它,但單詞topics后面不能有任何東西,否則就與該模式不匹配。其URL與該模式匹配的請求都將交給views.py中的函數topics()進行處理。

2.視圖

函數topics()需要從數據庫中獲取一些數據,并將其發送給模板。我們需要在views.py中添加的代碼如下:

from django.shortcuts import render
from .models import Topic ?
def index(request):
-- snip--
def topics(request):?
	"""
	顯示所有的主題
	"""
	topics = Topic.objects.order_by('date_added')?
	context = {'topics': topics} ?
	return render(request,'learning_logs/topics.html', context)?

我們首先導入了與所需數據相關聯的模型(見?)。函數topics()包含一個形參:Django從服務器那里收到的request對象(見?)。在?處,我們查詢數據庫——請求提供Topic對象,并按屬性date_added對它們進行排序。我們將返回的查詢集存儲在topics中。

在?處,我們定義了一個將要發送給模板的上下文。上下文是一個字典,其中的鍵是我們將在模板中用來訪問數據的名稱,而值是我們要發送給模板的數據。在這里,只有一個鍵—值對,它包含我們將在網頁中顯示的一組主題。創建使用數據的網頁時,除對象request和模板的路徑外,我們還將變量context傳遞給render()(見?)。

3.模板

顯示所有主題的頁面的模板接受字典context,以便能夠使用topics()提供的數據。請創建一個文件,將其命名為topics.html,并存儲到index.html所在的目錄中。下面演示了如何在這個模板中顯示主題:

{% extends "learning_logs/base.html" %}
{% block content %}
<p>Topics</p>
<ul>?
{% for topic in topics %}?
<li>{{ topic }}</li>?
{% empty %}?
<li>No topics have been added yet. </1i>
{% endfor %}?
</ul>?
{% endblock content %}

就像模板index.html一樣,我們首先使用標簽{ % extends % }來繼承base.html,再開始定義content塊。這個網頁的主體是一個項目列表,其中列出了用戶輸入的主題。在標準HTML中,項目列表被稱為無序列表,用標簽<ul></ul>表示。包含所有主題的項目列表始于?處。

在?處,我們使用了一個相當于for循環的模板標簽,它遍歷字典context中的列表topics。模板中使用的代碼與Python代碼存在一些重要差別:Python使用縮進來指出哪些代碼行是for循環的組成部分,而在模板中,每個for循環都必須使用{ % endfor %}標簽來顯式地指出其結束位置。因此在模板中,循環類似于下面這樣:

{% foritem in list %}
do something with each item
{% endfor %}

在循環中,我們要將每個主題轉換為一個項目列表項。要在模板中打印變量,需要將變量名用雙花括號括起來。每次循環時,?處的代碼{ { topic } }都被替換為topic的當前值。這些花括號不會出現在網頁中,它們只是用于告訴Django我們使用了一個模板變量。HTML標簽<li></li>表示一個項目列表項,在標簽對<ul></ul>內部,位于標簽<li></li>之間的內容都是一個項目列表項。

在?處,我們使用了模板標簽{ % empty % },它告訴Django在列表topics為空時該怎么辦:這里是打印一條消息,告訴用戶還沒有添加任何主題。最后兩行分別結束for循環(見?)和項目列表(見?)。

現在需要修改父模板,使其包含到顯示所有主題的頁面的鏈接:

基于Django3.0的web框架詳細架構過程是怎么樣的

我們在到主頁的鏈接后面添加了一個連字符(見?),然后添加了一個到顯示所有主題的頁面的鏈接——使用的也是模板標簽url(見?)。這一行讓Django生成一個鏈接,它與learning_logs/ urls.py中名為topics的URL模式匹配。

現在如果你刷新瀏覽器中的主頁,將看到鏈接Topics。單擊這個鏈接,將看到類似于圖18-4所示的網頁。

基于Django3.0的web框架詳細架構過程是怎么樣的

(三)顯示特定主題的頁面

接下來,我們需要創建一個專注于特定主題的頁面——顯示該主題的名稱及該主題的所有條目。同樣,我們將定義一個新的URL模式,編寫一個視圖并創建一個模板。我們還將修改顯示所有主題的網頁,讓每個項目列表項都是一個鏈接,單擊它將顯示相應主題的所有條目。

1.URL模式

顯示特定主題的頁面的URL模式與前面的所有URL模式都稍有不同,因為它將使用主題的id屬性來指出請求的是哪個主題。例如,如果用戶要查看主題Chess(其id為1)的詳細頁面,URL將為http://localhost:8000/topics/1/。下面是與這個URL匹配的模式,它包含在learning_logs/urls.py中:

django1.11改法

基于Django3.0的web框架詳細架構過程是怎么樣的

Django2.0改法:

我們來詳細研究這個URL模式中的正則表達式——r'^topics/(?P<topic_id>\d+)/$'。r讓Django將這個字符串視為原始字符串,并指出正則表達式包含在引號內。這個表達式的第二部分(/(?P<topic_id>\d+)/)與包含在兩個斜杠內的整數匹配,并將這個整數存儲在一個名為topic_id的實參中。這部分表達式兩邊的括號捕獲URL中的值;?P<topic_id>將匹配的值存儲到topic_id中;而表達式\d+與包含在兩個斜桿內的任何數字都匹配,不管這個數字為多少位。

發現URL與這個模式匹配時,Django將調用視圖函數topic(),并將存儲在topic_id中的值作為實參傳遞給它。在這個函數中,我們將使用topic_id的值來獲取相應的主題。

2.視圖

函數topic()需要從數據庫中獲取指定的主題以及與之相關聯的所有條目,如下所示:

views.py

--snip--
def topic(request,topic_id): ?
"""顯示單個主題及其所有的條目"""
topic = Topic.objects.get(id=topic_id)?
entries = topic.entry_set. order_by('-date_added')?
context = {'topic': topic, 'entries': entries} ?
return render(request,'learning_logs/topic.html', context)?

這是第一個除request對象外還包含另一個形參的視圖函數。這個函數接受正則表達式(?P<topic_id>\d+)捕獲的值,并將其存儲到topic_id中(見?)。在?處,我們使用get()來獲取指定的主題,就像前面在Django shell中所做的那樣。在?處,我們獲取與該主題相關聯的條目,并將它們按date_added排序:date_added前面的減號指定按降序排列,即先顯示最近的條目。我們將主題和條目都存儲在字典context中(見?),再將這個字典發送給模板topic.html(見?)。

注意 ?處和?處的代碼被稱為查詢,因為它們向數據庫查詢特定的信息。在自己的項目中編寫這樣的查詢時,先在Django shell中進行嘗試大有裨益。相比于編寫視圖和模板,再在瀏覽器中檢查結果,在shell中執行代碼可更快地獲得反饋。

3.模板

這個模板需要顯示主題的名稱和條目的內容;如果當前主題不包含任何條目,我們還需向用戶指出這一點:

topic.html

{% extends 'learning_logs/base.html' %}
{% block content %}
  <p>Topic: {{ topic }}</p> ?
  <p>Entries:</p>
  <ul>?
  {% for entry in entries %}?
    <li>
	  <p>{{ entry.date_added|date:'M d, Y H:i'}}</p>?
	  <!--其中的'|'表示模板過濾器,過濾器date:指定格式顯示日期-->
	  <p>{{ entry.text|linebreaks }}</p> ?
	  <!--過濾器linebreaks將包含換行符的長條目轉換成瀏覽器能識別的格式--></li>
  {% empty %}?
	<li>
	  There are no entries for this topic yet.
	</1i>
  {% endfor %}
  </ul>
{% endblock content %}

像這個項目的其他頁面一樣,這里也繼承了base.html。接下來,我們顯示當前的主題(見?),它存儲在模板變量{ { topic } }中。為什么可以使用變量topic呢?因為它包含在字典context中。接下來,我們開始定義一個顯示每個條目的項目列表(見?),并像前面顯示所有主題一樣遍歷條目(見?)。

每個項目列表項都將列出兩項信息:條目的時間戳和完整的文本。為列出時間戳(見?),我們顯示屬性date_added的值。在Django模板中,豎線(|)表示模板過濾器——對模板變量的值進行修改的函數。過濾器date: 'M d, Y H:i'以這樣的格式顯示時間戳:January 1, 2015 23:00。接下來的一行顯示text的完整值,而不僅僅是entry的前50個字符。過濾器linebreaks(見?)將包含換行符的長條目轉換為瀏覽器能夠理解的格式,以免顯示為一個不間斷的文本塊。在?處,我們使用模板標簽{ % empty % }打印一條消息,告訴用戶當前主題還沒有條目。

4.將顯示所有主題的頁面中的每個主題都設置為鏈接

在瀏覽器中查看顯示特定主題的頁面前,我們需要修改模板topics.html,讓每個主題都鏈接到相應的網頁,如下所示:

--snip--
	{% for topic in topics %}
	  <li>
		<a href=" {% url 'learning_logs:topic' topic.id %}">{{ topic }} </a>
	  </1i>
	{% empty %}
--snip--

我們使用模板標簽url根據learning_logs中名為topic的URL模式來生成合適的鏈接。這個URL模式要求提供實參topic_id,因此我們在模板標簽url中添加了屬性topic.id。現在,主題列表中的每個主題都是一個鏈接,鏈接到顯示相應主題的頁面,如http://localhost:8000/topics/1/。

如果你刷新顯示所有主題的頁面,再單擊其中的一個主題,將看到類似于下圖所示的頁面。

基于Django3.0的web框架詳細架構過程是怎么樣的

動手試一試

18-8 比薩店頁面:

在練習18-6中開發的項目Pizzeria中添加一個頁面,它顯示供應的比薩的名稱。然后,將每個比薩名稱都設置成一個鏈接,單擊這種鏈接將顯示一個頁面,其中列出了相應比薩的配料。請務必使用模板繼承來高效地創建頁面。

關于基于Django3.0的web框架詳細架構過程是怎么樣的就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

沿河| 翁牛特旗| 新密市| 大兴区| 浦东新区| 宣化县| 阿克陶县| 田林县| 徐水县| 深水埗区| 北流市| 哈尔滨市| 红桥区| 方正县| 株洲县| 漾濞| 景宁| 东丰县| 米易县| 吴旗县| 太保市| 堆龙德庆县| 贵阳市| 唐山市| 赤峰市| 体育| 盐池县| 出国| 荥经县| 濉溪县| 哈巴河县| 苍溪县| 平度市| 冀州市| 彭州市| 仪征市| 达孜县| 治县。| 竹北市| 德州市| 华蓥市|