在本教程中,我們將引導您完成一個投票應用程序的創建,它包含下面兩部分:
-
一個可以進行投票和查看結果的公開站點;
-
一個可以進行增刪改查的后台admin管理界面;
我們假設你已經安裝了Django。您可以通過運行以下命令來查看Django版本以及驗證是否安裝:
python -m django --version
如果安裝了Django,您應該將看到安裝的版本。如果沒有安裝,你會得到一個錯誤,提示No module named django
。
本教程是為Django 1.10和Python 3.4或更高版本編寫的。如果Django版本不匹配,您可以去官網參考您的對應Django版本的教程,或者將Django更新到最新版本。
如果你仍然在使用Python 2.7,你需要稍微調整代碼,注意代碼中的注釋。
創建project
如果這是你第一次使用Django,你將需要處理一些初始設置。也就是說,這會自動生成一些建立Django項目的代碼,但是你需要設置一些配置,包括數據庫配置,Django特定的選項和應用程序特定的設置等等。
從命令行,cd
進入您將存放項目代碼的目錄,然后運行以下命令:
django-admin startproject mysite # mysite為項目名
如果運行出錯,請參見Problems running django-admin。這將在目錄下生成一個mysite目錄,也就是你的這個Django項目的根目錄。它包含了一系列自動生成的目錄和文件,具備各自專有的用途。
注意: 在給項目命名的時候必須避開Django和Python的保留關鍵字。比如“django”(它會與Django本身沖突)或“test”(它與一個內置的Python包沖突)。
這些代碼應該放在哪兒? 如果你曾經學過普通的舊式的PHP(沒有使用過現代的框架),你可能習慣於將代碼放在Web服務器的文檔根目錄下(例如/var/www)。使用Django時,建議你不要這么做。 將Python代碼放在你的Web服務器的根目錄不是個好主意,因為這可能會有讓其他人看到你的代碼的風險。
一個新建立的項目結構大概如下:
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
這些文件分別是:
-
外層的mysite/根目錄僅僅是項目的一個容器。它的命名對Django無關緊要;你可以把它重新命名為任何你喜歡的名字;
-
manage.py:一個命令行工具,可以使你用多種方式對Django項目進行交互。 你可以在django-admin和manage.py中讀到關於manage.py的所有細節;
-
內層的mysite/目錄是你的項目的真正的Python包。它的名字是你引用內部文件的包名(例如 mysite.urls);
-
mysite/__init__.py
:一個空文件,它告訴Python這個目錄應該被看做一個Python包; -
mysite/settings.py:該Django項目的配置文件。具體內容可以參見Django settings;
-
mysite/urls.py: 路由文件,相當於你的Django站點的“目錄”。 你可以在URL轉發器中閱讀到關於URL的更多內容;
-
mysite/wsgi.py:用於你的項目的與WSGI兼容的Web服務器入口。用作服務部署,更多細節請參見如何利用WSGI進行部署。
開發服務器
讓我們驗證一下你的Django項目是否工作。 進入外層的mysite目錄,然后運行以下命令:
python manage.py runserver
你將在看到如下輸出:
Performing system checks...
System check identified no issues (0 silenced).
You have 13 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
January 09, 2017 - 16:22:02
Django version 1.10.2, using settings 'Django_learn.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
注意:現在忽略有關未應用數據庫遷移的警告;下面教程將很快處理數據庫
這表明你已經啟動了Django開發服務器,一個用純Python寫的輕量級Web服務器。 我們在Django中內置了它,這樣你就可以在不配置用於生產環境的服務器(例如Apache)的情況下快速開發出產品,直到你准備好上線。
請注意:不要在任何生產環境使用這個服務器。它僅僅是用於在開發中使用。(我們的重點是編寫Web框架,非Web服務器。)
既然服務器已經運行,請用你的瀏覽器訪問 http://127.0.0.1:8000。 在淡藍色背景下,你將看到一個“Welcome to Django”的頁面。 It worked!
修改端口號
默認情況下,runserver命令在內部IP的8000端口啟動開發服務器。
如果你需改變服務器的端口,把要使用的端口作為一個命令行參數傳遞給它。 例如,這個命令在8080端口啟動服務器:
python manage.py runserver 8080
如果你需改變服務器的IP地址,把IP地址和端口號放到一起。 因此若要監聽所有的外網IP,請使用(如果你想在另外一台電腦上展示你的工作,會非常有用):
python manage.py runserver 0.0.0.0:8000
runserver的自動重載
在Debug模式下,開發服務器會根據需要自動重新載入Python代碼。 你不必為了使更改的代碼生效而重啟服務器。 然而,一些行為比如添加文件,不會觸發服務器的重啟,所以在這種情況下你需要手動重啟服務器。
創建投票app
你編寫的每個Django應用都是遵循特定約定且包含一個Python包。 Django自帶這個功能,它可以自動生成應用的基本目錄結構(就像創建項目那樣)
project和app區別:
-
一個app實現某個功能,比如博客、公共檔案數據庫或者簡單的投票系統;
-
一個project是配置文件和多個app的集合,他們組合成整個站點;
-
一個project可以包含多個app;
-
一個app可以屬於多個project。
app的存放位置可以是任何地點,但是通常我們將它們都放在與manage.py同級目錄下,這樣方便導入文件。
進入mysite目錄,確保與manage.py文件處於同一級,並且鍵入以下命令來創建你的app:
python manage.py startapp polls # polls為app的name
這將創建一個目錄polls,它的結構如下:
polls/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
編寫視圖
讓我們寫第一個視圖。打開文件polls/views.py,並輸入以下Python代碼:
# polls/views.py
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the polls index.")
這是Django中最簡單的視圖。要調用視圖,我們需要將它映射到一個URL,為此,我們需要一個URLconf。
要在polls目錄中創建一個URLconf,在polls文件夾中創建一個名為urls.py的文件。您的應用目錄現在應該像這樣:
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.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
]
你可以看到項目根目錄下的mysite目錄也有個urls.py文件,下一步是讓這個項目的主urls.py文件指向我們建立的polls這個app獨有的urls.py文件,打開mysite/urls.py文件,你需要先導入include模塊,代碼如下:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^polls/', include('polls.urls')),
url(r'^admin/', admin.site.urls),
]
include語法相當於二級路由策略,它將接收到的url地址去除了它前面的正則表達式,將剩下的字符串傳遞給下一級路由進行判斷。
include的背后是一種即插即用的思想。項目根路由不關心具體app的路由策略,只管往指定的二級路由轉發,實現了解耦的特性。app所屬的二級路由可以根據自己的需要隨意編寫,不會和其它的app路由發生沖突。app目錄可以放置在任何位置,而不用修改路由。這是軟件設計里很常見的一種模式。
您現在已將索引視圖連接到URLconf。讓我們驗證它的工作,運行以下命令:
python manage.py runserver
在瀏覽器中訪問http//localhost8000/polls/,你應該看到文本“Hello, world. You’re at the polls index.“,就如你在view.py中定義的那樣。
url()函數可以傳遞4個參數,其中2個是必須的:regex和view,以及2個可選的參數:kwargs和name。下面是具體的解釋:
url() 參數:regex
regex是正則表達式的通用縮寫,它是一種匹配字符串或url地址的語法。Django拿着用戶請求的url地址,在urls.py文件中對urlpatterns列表中的每一項條目從頭開始進行逐一對比,一旦遇到匹配項,立即執行該條目映射的視圖函數或二級路由,其后的條目將不再繼續匹配。因此,url路由的編寫順序至關重要!
需要注意的是,regex不會去匹配GET或POST參數或域名,例如對於https://www.example.com/myapp, regex只嘗試匹配myapp/。對於https://www.example.com/myapp/?page=3, regex也只嘗試匹配myapp/
url() 參數:view
當正則表達式匹配到某個條目時,自動將封裝的HttpRequest對象作為第一個參數,正則表達式“捕獲”到的值作為第二個參數,傳遞給該條目指定的視圖。如果是簡單捕獲,那么捕獲值將作為一個位置參數進行傳遞,如果是命名捕獲,那么將作為關鍵字參數進行傳遞。
url() 參數:kwargs
任意數量的關鍵字參數可以作為一個字典傳遞給目標視圖。
url() argument: name
對你的URL進行命名,可以讓你能夠在Django的任意處,尤其是模板內顯式地引用它。相當於給URL取了個全局變量名,你只需要修改這個全局變量的值,在整個Django中引用它的地方也將同樣獲得改變。這是極為古老、朴素和有用的設計思想,而且這種思想無處不在。
快速通道
歡迎關注微信公眾號: Pythoner每日一報