編寫(xiě)你的第一個(gè) Django 應(yīng)用醋粟,第 1 部分
讓我們通過(guò)示例來(lái)學(xué)習(xí)凤价。
通過(guò)這個(gè)教程褥蚯,我們將帶著你創(chuàng)建一個(gè)基本的投票應(yīng)用程序。
它將由兩部分組成:
- 一個(gè)讓人們查看和投票的公共站點(diǎn)妈橄。
- 一個(gè)讓你能添加庶近、修改和刪除投票的管理站點(diǎn)。
我們假定你已經(jīng)閱讀了 安裝 Django眷蚓。你能知道 Django 已被安裝拦盹,且安裝的是哪個(gè)版本,通過(guò)在命令提示行輸入命令(由 $ 前綴)溪椎。
$ python -m django --version
如果這行命令輸出了一個(gè)版本號(hào),證明你已經(jīng)安裝了此版本的 Django恬口;如果你得到的是一個(gè)“No module named django”的錯(cuò)誤提示校读,則表明你還未安裝。
本教程適用于 Django 5.0祖能,支持 Python 3.10 及更高版本歉秫。如果 Django 版本不匹配,您可以使用本頁(yè)面右下角的版本切換器查看適用于您 Django 版本的教程养铸,或者將 Django 更新到最新版本雁芙。如果您使用的是較舊版本的 Python,請(qǐng)查看 我應(yīng)該使用哪個(gè)版本的 Python 來(lái)配合 Django? 以找到與之兼容的 Django 版本钞螟。
你可以查看文檔 如何安裝 Django 來(lái)獲得關(guān)于移除舊版本兔甘,安裝新版本的流程和建議。
從哪里獲得幫助:
如果你在閱讀本教程的過(guò)程中有任何疑問(wèn)鳞滨,可以前往 FAQ 的 獲取幫助 的版塊洞焙。
創(chuàng)建項(xiàng)目?
如果這是你第一次使用 Django 的話(huà),你需要一些初始化設(shè)置。也就是說(shuō)澡匪,你需要用一些自動(dòng)生成的代碼配置一個(gè) Django project —— 即一個(gè) Django 項(xiàng)目實(shí)例需要的設(shè)置項(xiàng)集合熔任,包括數(shù)據(jù)庫(kù)配置、Django 配置和應(yīng)用程序配置唁情。
打開(kāi)命令行疑苔,cd
到一個(gè)你想放置你代碼的目錄,然后運(yùn)行以下命令:
$ django-admin startproject mysite
這行代碼將會(huì)在當(dāng)前目錄下創(chuàng)建一個(gè) mysite
目錄甸鸟。如果命令失敗了惦费,查看 運(yùn)行 django-admin 時(shí)遇到的問(wèn)題,可能能給你提供幫助哀墓。
備注
你得避免使用 Python 或 Django 的內(nèi)部保留字來(lái)命名你的項(xiàng)目趁餐。具體地說(shuō),你得避免使用像 django
(會(huì)和 Django 自己產(chǎn)生沖突)或 test
(會(huì)和 Python 的內(nèi)置組件產(chǎn)生沖突)這樣的名字篮绰。
我的代碼該放在哪后雷?
如果你的背景是普通的老式 PHP(沒(méi)有使用過(guò)現(xiàn)代框架),你可能習(xí)慣于把代碼放在網(wǎng)絡(luò)服務(wù)器的文檔根目錄下(比如 /var/www
)吠各。在 Django 中臀突,你不需要這樣做。把任何 Python 代碼放在網(wǎng)絡(luò)服務(wù)器的文檔根目錄下都不是一個(gè)好主意贾漏,因?yàn)檫@有可能使人們能夠通過(guò)網(wǎng)絡(luò)查看你的代碼候学。這對(duì)安全沒(méi)有好處。
把你的代碼放在文檔根目錄 以外 的某些地方吧纵散,比如 /home/mycode梳码。
讓我們看看 startproject
創(chuàng)建了些什么:
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
這些目錄和文件的用處是:
- 最外層的
mysite/
根目錄只是你項(xiàng)目的容器, 根目錄名稱(chēng)對(duì) Django 沒(méi)有影響伍掀,你可以將它重命名為任何你喜歡的名稱(chēng)掰茶。 -
manage.py
: 一個(gè)讓你用各種方式管理 Django 項(xiàng)目的命令行工具。你可以閱讀 django-admin 和 manage.py 獲取所有manage.py
的細(xì)節(jié)蜜笤。 - 里面一層的
mysite/
目錄包含你的項(xiàng)目濒蒋,它是一個(gè)純 Python 包。它的名字就是當(dāng)你引用它內(nèi)部任何東西時(shí)需要用到的 Python 包名把兔。 (比如mysite.urls
). -
mysite/__init__.py
:一個(gè)空文件沪伙,告訴 Python 這個(gè)目錄應(yīng)該被認(rèn)為是一個(gè) Python 包。如果你是 Python 初學(xué)者县好,閱讀官方文檔中的 更多關(guān)于包的知識(shí)围橡。 -
mysite/settings.py
:Django 項(xiàng)目的配置文件。如果你想知道這個(gè)文件是如何工作的聘惦,請(qǐng)查看 Django 配置 了解細(xì)節(jié)某饰。 -
mysite/urls.py
:Django 項(xiàng)目的 URL 聲明儒恋,就像你網(wǎng)站的“目錄”。閱讀 URL調(diào)度器 文檔來(lái)獲取更多關(guān)于 URL 的內(nèi)容黔漂。 -
mysite/asgi.py
:作為你的項(xiàng)目的運(yùn)行在 ASGI 兼容的 Web 服務(wù)器上的入口诫尽。閱讀 如何使用 ASGI 來(lái)部署 了解更多細(xì)節(jié)。 -
mysite/wsgi.py
:作為你的項(xiàng)目的運(yùn)行在 WSGI 兼容的Web服務(wù)器上的入口炬守。閱讀 如何使用 WSGI 進(jìn)行部署 了解更多細(xì)節(jié)牧嫉。
用于開(kāi)發(fā)的簡(jiǎn)易服務(wù)器?
讓我們來(lái)確認(rèn)一下你的 Django 項(xiàng)目是否真的創(chuàng)建成功了。如果你的當(dāng)前目錄不是外層的 mysite
目錄的話(huà)减途,請(qǐng)切換到此目錄酣藻,然后運(yùn)行下面的命令:
$ python manage.py runserver
你應(yīng)該會(huì)看到如下輸出:
Performing system checks...
System check identified no issues (0 silenced).
You have unapplied migrations; your app may not work properly until they are applied.
Run 'python manage.py migrate' to apply them.
五月 07, 2024 - 15:50:53
Django version 5.0, using settings 'mysite.settings'
Starting development server at [http://127.0.0.1:8000/](http://127.0.0.1:8000/)
Quit the server with CONTROL-C.
備注
忽略有關(guān)未應(yīng)用最新數(shù)據(jù)庫(kù)遷移的警告,稍后我們處理數(shù)據(jù)庫(kù)鳍置。
你已經(jīng)啟動(dòng)了 Django 開(kāi)發(fā)服務(wù)器辽剧,這是一個(gè)用純 Python 編寫(xiě)的輕量級(jí)網(wǎng)絡(luò)服務(wù)器。我們?cè)?Django 中包含了這個(gè)服務(wù)器税产,所以你可以快速開(kāi)發(fā)怕轿,而不需要處理配置生產(chǎn)服務(wù)器的問(wèn)題 -- 比如 Apache -- 直到你準(zhǔn)備好用于生產(chǎn)。
現(xiàn)在是個(gè)提醒你的好時(shí)機(jī):千萬(wàn)不要 將這個(gè)服務(wù)器用于和生產(chǎn)環(huán)境相關(guān)的任何地方辟拷。這個(gè)服務(wù)器只是為了開(kāi)發(fā)而設(shè)計(jì)的撞羽。(我們?cè)诰W(wǎng)絡(luò)框架方面是專(zhuān)家,在網(wǎng)絡(luò)服務(wù)器方面并不是衫冻。)
服務(wù)器現(xiàn)在正在運(yùn)行诀紊,通過(guò)瀏覽器訪問(wèn) http://127.0.0.1:8000/ 。你將看到一個(gè)“祝賀”頁(yè)面隅俘,有一只火箭正在發(fā)射邻奠。你成功了!
更換端口
默認(rèn)情況下为居,runserver
命令會(huì)將服務(wù)器設(shè)置為監(jiān)聽(tīng)本機(jī)內(nèi)部 IP 的 8000 端口惕澎。
如果你想更換服務(wù)器的監(jiān)聽(tīng)端口,請(qǐng)使用命令行參數(shù)颜骤。舉個(gè)例子,下面的命令會(huì)使服務(wù)器監(jiān)聽(tīng) 8080 端口:
$ python manage.py runserver 8080
如果你想要修改服務(wù)器監(jiān)聽(tīng)的IP捣卤,在端口之前輸入新的忍抽。比如,為了監(jiān)聽(tīng)所有服務(wù)器的公開(kāi)IP(這你運(yùn)行 Vagrant 或想要向網(wǎng)絡(luò)上的其它電腦展示你的成果時(shí)很有用)董朝,使用:
$ python manage.py runserver 0.0.0.0:8000
關(guān)于這個(gè)簡(jiǎn)易服務(wù)器的完整信息可以在 runserver
文檔中找到鸠项。
會(huì)自動(dòng)重新加載的服務(wù)器 runserver
用于開(kāi)發(fā)的服務(wù)器在需要的情況下會(huì)對(duì)每一次的訪問(wèn)請(qǐng)求重新載入一遍 Python 代碼。所以你不需要為了讓修改的代碼生效而頻繁的重新啟動(dòng)服務(wù)器子姜。然而祟绊,一些動(dòng)作,比如添加新文件,將不會(huì)觸發(fā)自動(dòng)重新加載牧抽,這時(shí)你得自己手動(dòng)重啟服務(wù)器嘉熊。
創(chuàng)建投票應(yīng)用?
現(xiàn)在你的開(kāi)發(fā)環(huán)境——這個(gè)“項(xiàng)目” ——已經(jīng)配置好了,你可以開(kāi)始干活了扬舒。
在 Django 中阐肤,每一個(gè)應(yīng)用都是一個(gè) Python 包,并且遵循著相同的約定讲坎。Django 自帶一個(gè)工具孕惜,可以幫你生成應(yīng)用的基礎(chǔ)目錄結(jié)構(gòu),這樣你就能專(zhuān)心寫(xiě)代碼晨炕,而不是創(chuàng)建目錄了衫画。
項(xiàng)目 VS 應(yīng)用
項(xiàng)目和應(yīng)用有什么區(qū)別?應(yīng)用是一個(gè)專(zhuān)門(mén)做某件事的網(wǎng)絡(luò)應(yīng)用程序——比如博客系統(tǒng)瓮栗,或者公共記錄的數(shù)據(jù)庫(kù)削罩,或者小型的投票程序。項(xiàng)目則是一個(gè)網(wǎng)站使用的配置和應(yīng)用的集合遵馆。項(xiàng)目可以包含很多個(gè)應(yīng)用鲸郊。應(yīng)用可以被很多個(gè)項(xiàng)目使用。
你的應(yīng)用可以存放在任何 Python 路徑 中定義的路徑货邓。在這個(gè)教程中秆撮,我們將在你的 manage.py
同級(jí)目錄下創(chuàng)建投票應(yīng)用。這樣它就可以作為頂級(jí)模塊導(dǎo)入换况,而不是 mysite
的子模塊职辨。
請(qǐng)確定你現(xiàn)在處于 manage.py
所在的目錄下,然后運(yùn)行這行命令來(lái)創(chuàng)建一個(gè)應(yīng)用:
$ python manage.py startapp polls
這將創(chuàng)建一個(gè)名為 polls
的目錄戈二,其布局如下:
polls/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
這個(gè)目錄結(jié)構(gòu)包括了投票應(yīng)用的全部?jī)?nèi)容舒裤。
編寫(xiě)第一個(gè)視圖?
讓我們開(kāi)始編寫(xiě)第一個(gè)視圖吧。打開(kāi) polls/views.py
觉吭,把下面這些 Python 代碼輸入進(jìn)去:
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the polls index.")
這是 Django 中最簡(jiǎn)單的視圖腾供。如果想看見(jiàn)效果,我們需要將一個(gè) URL 映射到它——這就是我們需要 URLconf 的原因了鲜滩。
要在 polls 目錄中創(chuàng)建一個(gè) URL 配置伴鳖,請(qǐng)創(chuàng)建一個(gè)名為 urls.py
的文件。現(xiàn)在你的應(yīng)用程序目錄應(yīng)該如下所示:
polls/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
urls.py
views.py
在 polls/urls.py
中徙硅,輸入如下代碼:
polls/urls.py
?
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
]
下一步是要在根 URLconf 文件中指定我們創(chuàng)建的 polls.urls
模塊榜聂。在 mysite/urls.py
文件的 urlpatterns
列表里插入一個(gè) include()
, 如下:
mysite/urls.py
?
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path("polls/", include("polls.urls")),
path("admin/", admin.site.urls),
]
函數(shù) include()
允許引用其它 URLconfs嗓蘑。每當(dāng) Django 遇到 include()
時(shí)须肆,它會(huì)截?cái)嗯c此項(xiàng)匹配的 URL 的部分匿乃,并將剩余的字符串發(fā)送到 URLconf 以供進(jìn)一步處理。
我們?cè)O(shè)計(jì) include()
的理念是使其可以即插即用豌汇。因?yàn)橥镀睉?yīng)用有它自己的 URLconf( polls/urls.py
)幢炸,他們能夠被放在 "/polls/" , "/fun_polls/" 瘤礁,"/content/polls/"阳懂,或者其他任何路徑下,這個(gè)應(yīng)用都能夠正常工作柜思。
何時(shí)使用
include()
當(dāng)包括其它 URL 模式時(shí)你應(yīng)該總是使用include()
岩调,admin.site.urls
是唯一例外。
你現(xiàn)在把 index
視圖添加進(jìn)了 URLconf赡盘。通過(guò)以下命令驗(yàn)證是否正常工作:
$ python manage.py runserver
用你的瀏覽器訪問(wèn) http://localhost:8000/polls/号枕,你應(yīng)該能夠看見(jiàn) "Hello, world. You're at the polls index." ,這是你在 index
視圖中定義的陨享。
沒(méi)有找到頁(yè)面?
如果你在這里得到了一個(gè)錯(cuò)誤頁(yè)面葱淳,檢查一下你是不是正訪問(wèn)著http://localhost:8000/polls/ 而不應(yīng)該是 http://localhost:8000/。
函數(shù) path()
具有四個(gè)參數(shù)抛姑,兩個(gè)必須參數(shù):route
和 view
赞厕,兩個(gè)可選參數(shù):kwargs
和 name
。現(xiàn)在定硝,是時(shí)候來(lái)研究這些參數(shù)的含義了皿桑。
path()
參數(shù): route
?
route
是一個(gè)匹配 URL 的準(zhǔn)則(類(lèi)似正則表達(dá)式)。當(dāng) Django 響應(yīng)一個(gè)請(qǐng)求時(shí)蔬啡,它會(huì)從 urlpatterns
的第一項(xiàng)開(kāi)始诲侮,按順序依次匹配列表中的項(xiàng),直到找到匹配的項(xiàng)箱蟆。
這些準(zhǔn)則不會(huì)匹配 GET 和 POST 參數(shù)或域名沟绪。例如,URLconf 在處理請(qǐng)求 https://www.example.com/myapp/
時(shí)空猜,它會(huì)嘗試匹配 myapp/
绽慈。處理請(qǐng)求 https://www.example.com/myapp/?page=3
時(shí),也只會(huì)嘗試匹配 myapp/
辈毯。
path()
參數(shù): view
?
當(dāng) Django 找到了一個(gè)匹配的準(zhǔn)則久信,就會(huì)調(diào)用這個(gè)特定的視圖函數(shù),并傳入一個(gè) HttpRequest
對(duì)象作為第一個(gè)參數(shù)漓摩,被“捕獲”的參數(shù)以關(guān)鍵字參數(shù)的形式傳入。稍后入客,我們會(huì)給出一個(gè)例子管毙。
path()
參數(shù): kwargs
?
任意個(gè)關(guān)鍵字參數(shù)可以作為一個(gè)字典傳遞給目標(biāo)視圖函數(shù)腿椎。本教程中不會(huì)使用這一特性。
path()
參數(shù): name
?
為你的 URL 取名能使你在 Django 的任意地方唯一地引用它夭咬,尤其是在模板中啃炸。這個(gè)有用的特性允許你只改一個(gè)文件就能全局地修改某個(gè) URL 模式。