Django是一個Web框架——一套用於幫助開發交互式網站的工具。Django可以響應網頁請求,還能讓你更輕鬆地讀寫數據庫、管理用戶等。html
開始編寫一個名爲「學習筆記」的Web應用程序,讓用戶可以記錄感興趣的主題,並在學習每一個主題的過程當中添加日誌條目。「學習筆記」的主頁對這個網站進行描述,並邀請用戶註冊或登陸。用戶登陸後,就能夠建立主題、添加新條目以及閱讀既有的條目。python
File->New Project,設置以下
web
cmd
進入終端,cd到python安裝的Script文件夾下,利用pip命令安裝Django,或將python安裝目錄Script文件夾路徑加入環境變量中,則可直接使用pip命令。pip install django
命令安裝Django在Pycharm中新建的項目中,利用Terminal終端在虛擬環境下使用django-admin startproject project-name .
建立項目,注意命令後的點號,書上提到,忘記點號在部署應用程序時會遇到一些配置問題。忘記點號,就將建立的目錄文件夾刪除再運行一邊命令正則表達式
Django在項目中新建了一個名爲learnning_log的目錄,其中最重要的是settings.py、urls,py、wsgi.pysql
還建立了一個名爲manage.py的文件,這是一個簡單的程序,它接受命令並將其交給Django的相關部分去運行。咱們將使用這些命令來管理諸如使用數據庫和運行服務器等任務shell
使用migrate
命令建立一個供Django使用的數據庫:python manage.py migrate
數據庫
咱們將修改數據庫稱爲遷移數據庫。首次執行命令migrate時,將讓Django確保數據庫與項目的當前狀態匹配。在使用SQLite的新項目中首次執行這個命令時,Django將建立一個數據庫django
運行過命令後,咱們會發現,項目中多出來了一個db.sqlite3文件,SQLite是一種使用單個文件的數據庫,是編寫簡單應用程序的理想選擇,由於它讓你不用太關注數據庫管理的問題瀏覽器
執行命令runserver,合適Django是否正確地建立了項目:python manage.py runserver
服務器
Django啓動一個服務器,讓你可以查看系統中地項目,瞭解他們地工做。當瀏覽器中輸入url請求網頁時,該Django服務器將進行響應:生成合適地網頁,並將其發送給瀏覽器
注意 若是出現錯誤消息 「That portis already iin use"(指定端口已被佔用),請執行
python manage.py runserver 8001
,讓Django使用另外一個端口;若是這個端口也不可用,請不斷執行上述命令,更改其中指定的端口號,直到找到可用的端口。
Django項目由一系列應用程序組成,它們協同工做,讓項目成爲一個總體。我接下來建立一個應用程序,他將完成項目的大部分工做。
當前,在前面打開的終端窗口運行着runserver
。咱們再打開一個終端窗口,執行命令startapp
命令startapp appname讓Django創建建立應用程序的基礎設施。如今查看項目目錄,新增了一個文件夾learning_logs
該文件夾中最重要的文件是models.py、admin.py、views.py
接下來使用models.py來定義咱們在應用程序中管理的數據
咱們考慮設計的數據。每位用戶在學習筆記中須要建立不少主題。用戶輸入每一個條目都與特定主題相關聯,這些條目以文本的形式顯示。咱們還須要存儲每一個條目的時間戳,以便可以告訴用戶各個條目都是何時建立的
打開models.py,它爲咱們導入了模塊models,咱們還能建立本身的模型。模型告訴Django如何處理應用程序中存儲的數據。如今咱們建立一個名爲Topic的類,繼承Model,表示用戶將存儲的主題的模型,它包含text和date_added兩個屬性
要使用模型,必須讓Django將應用程序包含到項目中,爲此應該在settings.py中的INSTALLED_APPS片斷中添加咱們的應用程序信息
接下來,須要讓Django修改數據庫,使其可以存儲與模型Topic相關的信息。爲此,在終端窗口執行makemigrations
命令讓Django肯定該如何修改數據庫,執行後Django將建立一個遷移文件在數據庫中爲模型Topic建立一個表
下面,使用migrate
來應用這種遷移,讓Django替咱們修改數據庫
爲應用程序定義模型時,Django提供的管理網站admin site讓咱們可以輕鬆地處理模型。接下來,咱們就創建管理網站,並經過它使用模型Topic來添加一些主題
建立超級用戶:
執行python manage.py createsuperuser
命令在Django中建立超級用戶,執行命令後,Django提示輸入超級用戶的用戶名(默認)、郵箱(可放空)、密碼、確認密碼
向管理網站註冊模型:
在models.py所在目錄中的admin.py文件中輸入下面代碼向管理網站註冊Topic
from learning_logs.models import Topic admin site.register(Topic)
如今使用超級用戶帳戶訪問登陸網站:http://localhost:8000/admin/ ,輸入剛建立的超級用戶的用戶名和密碼,進入以下界面(Django administration)。這個網頁能讓咱們添加和修改用戶和用戶組,還能夠管理剛纔定義的模型Topic相關的數據,接下來,咱們來添加第一個主題
添加主題:
單擊Topics進入主題網頁,它幾乎是空的,由於咱們尚未添加任何主題
單擊Add,看到一個用於添加新主題的表單,在第一個輸入框中輸Chess,再單擊Save,這將返回主題管理頁面,其中剛建立的主題已被添加,按照該步驟咱們再建立一個Rock Climbing主題
特定主題下有用戶在學習筆記記錄的知識條目,這是一種多對一關係,即多個知識條目關聯到同一個主題
像Topic同樣,咱們建立Entry模型,它繼承Django基類Model,擁有topic、text、date_added三個屬性
遷移模型Entry:
因爲咱們新添加了一個新模型,所以須要再次遷移數據庫
這個過程是:
python manage.py makemigrations app_name
python manage.py migrate
生成了一個新的遷移文件,告訴Django如何修改數據庫,使其能存儲與模型Entry相關的信息,而後執行migrate,應用遷移
向管理網站註冊Entry:
在admin.py中註冊模型Entry
返回http://localhost:8000/admin/,你將看到learing_logs下列出了Entries,單擊Entries的Add連接或單擊Entries再選擇Add entry。
你將看到一個下拉列表,能選擇要建立哪一個主題的條目,還有一個輸入條目的文本框。咱們添加一個Chess主題的條目,以下:
返回條目管理頁面,咱們能看到添加的條目以及使用text[:50]呈現出來的條目信息
使用Django建立網頁的過程一般分三個階段:定義URL、編寫視圖和編寫模板。首先,你必須定義URL模式。URL模式描述了URL是如何設計的,讓Django知道如何將瀏覽器請求與網站URL匹配,以肯定返回哪一個網頁。
每一個URL都被映射到特定的視圖——視圖函數獲取並處理網頁所需的數據。視圖函數一般條用一個模板,後者生成瀏覽器可以理解的網頁。咱們接下來建立學習筆記的主頁。咱們將定義主頁的URL、編寫其視圖函數並建立一個簡單的模板
鑑於咱們只是要確保」學習筆記「按要求的那樣工做,咱們將暫時讓這個網頁儘量簡單。Web應用程序可以正常運行後,設置樣式可以使其更有趣,但中看不中用的應用程序毫無心義。目前的主頁只顯示標題和簡單的描述。
用戶經過在瀏覽器中輸入URL以及單擊連接來請求網頁,所以咱們須要肯定項目所需的URL。
當前,基礎URL(http://localhost:8000/ )返回默認的Django網站,讓咱們知道正確創建了項目。咱們將修改這一點,讓這個基礎URL映射到」學習筆記「的主頁
首先,咱們修改項目文件夾中的urls.py
urls.py文件的urlpatterns主體包含了項目中的應用程序的URL。其中的admin.site.urls定義了可在管理網站中請求的全部URL
咱們添加了learning_logs.urls幷包含namespace將learning_logs的URL同項目中的其餘URL區分開來,這在項目擴展時頗有幫助
因此咱們又須要在文件夾learning_logs中建立另外一個urls.py文件:
在應用程序的urls.py中,咱們導入了url模塊用於將URL映射到視圖,還導入了views模塊,其中的句點表示讓Python從當前的urls.py模塊所在的文件夾中導入視圖。變量urlpatterns是一個包含了可在應用程序learning_logs中請求的網頁
實際的URL模式是一個對函數url()
的調用,這個函數接受三個實參:
r'^$'
,其中的r
讓Python將接下來的字符串視爲原始字符串,引號包括正則表達式的起止。脫字符^
讓Python查看字符串的開頭,美圓符$
讓Python查看字符串末尾視圖函數接受請求中的信息,準備好生成網頁所需的數據,再將這些數據發送給服務器
咱們在learning_logs應用程序的views.py中爲主頁編寫視圖,以下:
URL請求與咱們剛纔定義的模式匹配時,Django將在文件views.py中查找函數index(),再將請求對象傳遞給這個視圖函數。在這裏,咱們不用處理任何數據,所以這個函數只調用render(),向它提供兩個實參:原始請求對象以及一個用於建立網頁的模板。接下來就是編寫模板了
模板定義了網頁的結構。模板定義了網頁是什麼樣的,每當網頁被請求時,Django將填入相關的數據。模板讓你可以訪問試圖提供的任何數據。
咱們在learning_logs中新建一個文件夾,將其命名爲templates,在templates中再建立一個learning_logs文件夾(這彷佛有些多餘?但創建了Django可以明確解讀的結構,即便項目很大,包含不少應用程序亦如此)。而後建立index.html文件,編寫index.html代碼
<p>Learning Log</p> <P>Learning Log helps you keep track of your learning, for any topic you're learning about.</p>
如今,咱們再請求項目的基礎URL——http://localhost:8000/ ,將看到剛纔建立的網頁,而不是默認的Django網頁。Django接受請求的URL匹配了模式r'^$'
,所以調用函數views.index(),因而使用index.html包含的模板來渲染網頁,結果以下
制定建立網頁的流程後,能夠開始擴充」學習筆記「的項目了。咱們將建立兩個顯示數據的網頁,其中一個列出全部的主題,另外一個顯示指定主題的全部條目。對於每一個網頁咱們都將指定URL模式,編寫一個視圖函數,並編寫一個模板。
建立網站時,幾乎都有一些全部網頁都將包含的元素。在這種狀況下,能夠編寫一個包含通用元素的父模板,並讓每一個網頁都繼承這個模板,而沒必要在每一個網頁中重複定義這些通用元素。這種方法讓你能專一於開發每一個網頁的獨特方面,還能讓修改項目的總體外觀容易不少
咱們在learning_logs/templates/learning_logs下建立咱們的模板
建立一個base.html
其中咱們使用了模板標籤{% %}
,模板標籤是一小段代碼,生成要在網頁中顯示的信息。這裏,模板標籤{% url 'learning_logs:index' %}
生成一個url,該url於learning_logs/urls.py中定義的名爲index的URL模式匹配
利用模板標籤來生成URL,有利於更新連接。要修改項目中的URL,只需修改urls.py中的URL模式,這樣網頁被請求時,Django自動插入修改後的URL
重寫index.html,使其繼承base.html,以下
標籤{% extends %}
指定繼承的父模板
標籤{% block %}
定義content塊,再使用{% endblock content %}
指定了內容定義的結束位置
這裏,模板繼承的優勢開始顯現出來了:在子模版中,只需包含當前網頁特有的網內容。
URL模式
這個模式與這樣的URL匹配:基礎URL後面跟着topics,能夠在末尾包含斜槓,也能夠省略它,但單詞topics後面不能又任何東西,不然就與該模式不匹配。該模式匹配的請求都交給views.py中的函數topics()處理
視圖
導入所需數據相關聯的Topic模型,將Topic對象按屬性date_added排序,存入一個上下文字典中,建立使用數據的網頁時,除對象request和模板的路徑外,咱們還將變量context傳遞給render()
模板
與模板index.html相似的,topics.html繼承base.html父模板
咱們使用了一個至關於for循環的模板標籤,遍歷字典context中的列表topics,{{ topic }}
是一個模板變量,Django會將這部分替換爲topic的當前值
咱們還使用了模板標籤{{% empty % }}
告訴Django在topics列表爲空的時候怎麼辦
如今修改父模板,使其包含到顯示全部主題的頁面的連接
到瀏覽器主頁單擊Topics連接看到以下網頁
URL模式
咱們再看看這個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函數中包含了一個形參,咱們使用get()獲取topic_id指定的主題,使用entry_set.order_by()獲取降序排序的條目。這是一種查詢,在本身的項目中編寫相似的查詢時,咱們應該使用Django shell先進行嘗試。而後把查詢結果存入字典中發送給模板topic.html
模板
該模板也繼承了base.html父模板
特別的,在該模板中咱們使用了模板過濾器|
用一個豎線表示。例如date: 'M d, Y H:i'
以這樣的格式顯示時間戳:January 1,2015 23:00
,過濾器linebreaks
將包含換行符的長條目轉換成瀏覽器可以理解的格式,以避免顯示一個不間斷的文本塊
將顯示全部主題的頁面中的每一個主題都設置爲連接
在topics請求頁面中,連接到顯示相應主題的頁面,如http://localhost:8000/topics/1/ ,結果以下