python:3.7.2html
Django:2.1.7python
虛擬環境是系統的一個位置,能夠在其中安裝包,並將其與其餘python包隔離。web
建立目錄,命名爲learning_log,並切換到這個目錄下,並建立一個虛擬環境。正則表達式
$ mkdir learning_log
$ cd learning_log/
learning_log$ python3 -m venv ll_env
learning_log$ source ll_env/bin/activate
(ll_env)learning_log$ pip3 install Django
在處於活動的虛擬環境的狀況下(ll_env包含在括號內,如下的步驟都是在虛擬環境下),執行以下命令來新建項目:sql
(ll_env)learning_log$ django-admin.py startproject learning_log . # 建立項目,點號是讓新項目使用合適的目錄結構,不能缺乏。 (ll_env)learning_log$ ls # Django新建了一個名爲learning_log的目錄。它還建立了一個名爲manage.py的文件 learning_log ll_env manage.py (ll_env)learning_log$ ls learning_log # learning_log包含4個文件 __init__.py settings.py urls.py wsgi.py
settings.py:指定Django如何與你的系統交互以及如何管理項目。在開發項目的過程當中,咱們將修改其中一些設置,並添加一些設置。shell
urls.py:告訴Django應建立哪些網頁來響應瀏覽器請求。數據庫
wsgi.py:幫助Django提供它建立的文件,這個文件名是web server gateway interface(Web服務器網關接口 )的首字母縮寫。django
(ll_env)learning_log$ python3 manage.py migrate
Operations to perform:...
將修改數據庫稱爲遷移數據庫。首次執行命令migrate 時,將讓Django確保數據庫與項目的當前狀態匹配。Django將新建一個數據庫。Django指出它將建立必要的數據庫表,用於存儲咱們將在這個項目(Synchronize unmigrated apps,同步未遷移的應用程序 )中使用的 信息,再確保數據庫結構與當前代碼(Applyallmigrations,應用全部的遷移 )匹配。編程
(ll_env)learning_log$ ls
db.sqlite3 learning_log ll_env manage.py
咱們運行了命令ls ,其輸出代表Django又建立了一個文件——db.sqlite3。SQLite是一種使用單個文件的數據庫,是編寫簡單應用程序的理想選擇,由於它讓你不用太關 注數據庫管理的問題。瀏覽器
(ll_env)learning_log$ python3 manage.py runserver 0.0.0.0:405 # 容許全部IP地址訪問,使用405端口 Performing system checks... System check identified no issues (0 silenced). # 檢查確認正確地建立了項目 March 06, 2019 - 01:45:25 Django version 2.1.7, using settings 'learning_log.settings' # Django版本以及設置文件的名稱 Starting development server at http://0.0.0.0:405/ # 訪問地址和端口,若是出現端口占用,則嘗試其餘端口 Quit the server with CONTROL-C.
新開另外一個終端窗口,並切換到manage.py所在的目錄,激活該虛擬環境,並執行命令startapp。
learning_log$ source ll_env/bin/activate (ll_env)learning_log$ python3 manage.py startapp learning_logs # 建立應用程序 (ll_env)learning_log$ ls # 新增了文件夾learning_logs db.sqlite3 learning_log learning_logs ll_env manage.py (ll_env)learning_log$ ls learning_logs/ # 最重要的文件是models.py、admin.py和views.py admin.py __init__.py migrations models.py tests.py views.py
模型models.py(在learning_logs目錄下面)用於定義咱們要在應用程序中管理的數據。在代碼層面,模型就是一個類,就像前面討論的每一個類同樣,包含屬性 和方法。下面是表示用戶將要存儲的主題的模型:
from django.db import models class Topic(models.Model): # 建立Topic主題的類 """用戶學習的主題""" text = models.CharField(max_length=200) date_added = models.DateTimeField(auto_now_add=True) def __str__(self): # 默認應使用哪一個屬性來顯示有關主題的信息,若是是python2.7,應調用__unicode__() """返回模型的字符串表示""" return self.text
其餘的屬性能夠參考:https://docs.djangoproject.com/en/1.8/ref/models/fields/ 。
須要在learning_log文件夾修改settings.py文件,告訴Django哪些應用程序安裝到learning_log項目中。
請將INSTALLED_APPS(這是個元組) 修改爲下面這樣,將前面的應用程序名稱添加到這個元組中:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # 個人應用程序 'learning_logs', ]
接下來,須要讓Django修改數據庫,使其可以存儲與模型Topic 相關的信息。爲此,在終端窗口中執行下面的命令:
(ll_env)learning_log$ python3 manage.py makemigrations learning_logs
Migrations for 'learning_logs': 0001_initial.py: - Create model Topic
命令makemigrations 讓Django肯定該如何修改數據庫,使其可以存儲與咱們定義的新模型相關聯的數據。輸出代表Django建立了一個名爲0001_initial.py的遷移文件,這個文件將在數據庫中爲模型Topic 建立一個表。
下面來應用這種遷移,讓Django替咱們修改數據庫:
(ll_env)learning_log$ python3 manage.py migrate --snip-- Running migrations: Rendering model states... DONE Applying learning_logs.0001_initial... OK # 應用遷移正常
每當須要修改「學習筆記」管理的數據時,都採起以下三個步驟:
(1)建立超級用戶:建立具有全部權限的用戶。
(ll_env)learning_log$ python3 manage.py createsuperuser
(2)向管理網站註冊模型:咱們建立應用程序learning_logs 時,Django在models.py所在的目錄中建立了一個名爲admin.py的文件。爲向管理網站註冊Topic ,請在admin.py輸入下面的代碼:
from django.contrib import admin from learning_logs.models import Topic admin.site.register(Topic)
如今,使用超級用戶帳戶訪問管理網站:訪問http://localhost:8000/admin/ ,並輸入你剛建立的超級用戶的用戶名和密碼,你將看到相似於下圖所示的屏幕。這個網頁讓你可以添加和修改用戶和用戶組,還能夠管理與剛纔定義的模型Topic 相關的數據。
(3)添加主題:向管理網站註冊Topic 後,咱們來添加第一個主題。爲此,單擊Topics進入主題網頁,它幾乎是空的,這是由於咱們尚未添加任何主題。單擊Add,你將看到一個用於添加新主題的表單。在第一個方框中輸入Chess ,再單擊Save,這將返回到主題管理頁面,其中包含剛建立的主題。
修改models.py中的代碼:
# 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 class Entry(models.Model): # 繼承了Django基類Model """學到的有關某個主題的具體指示""" topic = models.ForeignKey(Topic,on_delete=models.CASCADE) # 外鍵。每一個主題建立時,都給它分配了一個鍵(或ID). text = models.TextField() # 不須要長度限制 date_added = models.DateTimeField(auto_now_add=True) class Meta: # 用於管理模型的額外信息,在須要時使用Entries來表示多個條目。若沒有,將使用Entrys來表示多個條目。 verbose_name_plural = 'entries' def __str__(self): # 只呈現text前50個字符。 """返回模型的字符串表示""" return self.text[:50] + "..."
因爲咱們添加了一個新模型,所以須要再次遷移數據庫。
將慢慢地對這個過程瞭如指掌:
(ll_env)learning_log$ python3 manage.py makemigrations learning_logs Migrations for 'learning_logs': learning_logs/migrations/0002_entry.py # 生成了一個新的遷移文件0002_... - Create model Entry
(ll_env)learning_log$ python3 manage.py migrate
咱們還須要註冊模型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:405/admin/learning_logs/ ,你將看到learning_logs下列出了Entries:
單擊Entries的Add連接,或者單擊Entries再選擇Add entry。你將看到一個下拉列表,讓你可以選擇要爲哪一個主題創 建條目,還有一個用於輸入條目的文本框。從下拉列表中選擇Chess,並添加一個條目(略)。
輸入一些數據後,就可經過交互式終端會話以編程方式查看這些數據了。命令python manage.py shell啓動一個Python解釋器,可以使用它來探索存儲在項目數據庫中的數據。
(ll_env)learning_log$ python3 manage.py shell >>> from learning_logs.models import Topic >>> Topic.objects.all() <QuerySet [<Topic: Chess>, <Topic: Rock Climbing>]> >>> topics = Topic.objects.all() >>> for topic in topics: ... print(topic.id, topic) ... 1 Chess 2 Rock Climbing >>> t = Topic.objects.get(id=1) >>> t.text 'Chess'>>> t.date_added datetime.datetime(2019, 3, 7, 2, 14, 27, 770273, tzinfo=<UTC>) >>> t.entry_set.all() <QuerySet [<Entry: The opening is the first part of the game, roughly...>, <Entry: In the opening phase of the game, it's important t...>]>
使用Django建立網頁的過程一般分三個階段:定義URL、編寫視圖和編寫模板。首先,你必須定義URL模式。URL模式描述了URL是如何設計的,讓Django知道如何將瀏覽器請求 與網站URL匹配,以肯定返回哪一個網頁。
每一個URL都被映射到特定的視圖 ——視圖函數獲取並處理網頁所需的數據。視圖函數一般調用一個模板,後者生成瀏覽器可以理解的網頁。爲明白其中的工做原理,咱們來建立 學習筆記的主頁。咱們將定義該主頁的URL、編寫其視圖函數並建立一個簡單的模板。
(1)映射URL
用戶經過在瀏覽器中輸入URL以及單擊連接來請求網頁,所以咱們須要肯定項目須要哪些URL。主頁的URL最重要,它是用戶用來訪問項目的基礎URL。當前,基礎
URL(http://localhost:8000/)返回默認的Django網站,讓咱們知道正確地創建了項目。咱們將修改這一點,將這個基礎URL映射到「學習筆記」的主頁。
打開項目主文件夾learning_log中的文件urls.py,咱們須要在原來的基礎上包含learning_logs的URL:
from django.contrib import admin from django.conf.urls import url, include urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'', include('learning_logs.urls',namespace='learning_logs')), # 包含earning_logs.urls內容 ]
在文件夾learning_logs中建立另外一個urls.py文件:
"""定義learning_logs的URL模式""" from django.conf.urls import url # 函數url用於建立URL映射到視圖 from . import views # 當前的urls.py模塊所在的文件夾中導入視圖 app_name='learning_logs' # 防止出現錯誤:Specifying a namespace in include() without providing an app_name urlpatterns = [ # 主頁 url(r'^$', views.index, name='index'), ]
url()函數接受三個實參:
(2)編寫視圖
修改learning_logs中的文件views.py文件:
from django.shortcuts import render def index(request): """學習筆記的主頁""" return render(request, 'learning_logs/index.html')
URL請求與咱們剛纔定義的模式匹配時,Django將在文件views.py中查找函數index() ,再將請求對象傳遞給這個視圖函數。在這裏,咱們不須要處理任何數據,所以這個函數只 包含調用render() 的代碼。這裏向函數render() 提供了兩個實參:原始請求對象以及一個可用於建立網頁的模板。下面來編寫這個模板。
(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>
如今,若是你請求這個項目的基礎URL——http://localhost:8000/,將看到剛纔建立的網頁,而不是默認的Django網頁。Django接受請求的URL,發現該URL與模式r'^$' 匹配,所以 調用函數views.index() ,這將使用index.html包含的模板來渲染網頁,結果以下圖所示。
咱們將建立兩個顯示數據的網頁,其中一個列出全部的主題,另外一個顯示特定主題的全部條目。對於每一個網頁,咱們 都將指定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模式。
咱們插入了一對塊標籤。這個塊名爲content ,是一個佔位符,其中包含的信息將由子模板指定。子模板並不是必須定義父模板中的每一個塊,所以在父模板中,可以使用任意多個塊來預留空間,而子模板可根據須要定義相應數量的塊。
在Python代碼中,咱們幾乎老是縮進四個空格。相比於Python文件,模板文件的縮進層級更多,所以每一個層級一般只縮進兩個空格。
(2)子模塊
如今須要從新編寫index.html,使其繼承base.html,以下所示:
{% extends "learning_logs/base.html" %} {% block content %} <p>Learning Log</p> <p>Learning Log helps you keep track of your learning, for any topic you're learning about.</p> {% endblock content %}
若是將這些代碼與原來的index.html進行比較,可發現咱們將標題LearningLog替換成了從父模板那裏繼承的代碼。子模板的第一行必須包含標籤{% 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,所以URL http://localhost:8000/topics/將返回顯示全部 主題的頁面。下面演示了該如何修改learning_logs/urls.py:
"""定義learning_logs的URL模式""" from django.conf.urls import url from . import views app_name='learning_logs' urlpatterns = [ # 主頁 url(r'^$', views.index, name='index'), # 顯示全部的主題 url(r'^topics/$', views.topics, name='topics'), ]
咱們只是在用於主頁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): """學習筆記的主頁""" return render(request, 'learning_logs/index.html') 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.</li> {% endfor %} </ul> {% endblock content %}
就像模板index.html同樣,咱們首先使用標籤{% extends %}來繼承base.html,再開始定義content塊。這個網頁的主體是一個項目列表,其中列出了用戶輸入的主題。在標準 HTML中,項目列表被稱爲無序列表,用標籤<ul></ul> 表示。
咱們使用了一個至關於for 循環的模板標籤,它遍歷字典context 中的列表topics 。模板中使用的代碼與Python代碼存在一些重要差異:Python使用縮進來指出哪些 代碼行是for循環的組成部分,而在模板中,每一個for循環都必須使用{% endfor %}標籤來顯式地指出其結束位置。所以在模板中,循環相似於下面這樣:
{% for item in list %} do something with each item {% endfor %}
在循環中,咱們要將每一個主題轉換爲一個項目列表項。要在模板中打印變量,須要將變量名用雙花括號括起來。每次循環時,代碼{{ topic }}都被替換爲topic的當 前值。這些花括號不會出如今網頁中,它們只是用於告訴Django咱們使用了一個模板變量。HTML標籤<li></li> 表示一個項目列表項,在標籤對<ul></ul> 內部,位於標 籤<li> 和</li> 之間的內容都是一個項目列表項。
咱們使用了模板標籤{% empty %},它告訴Django在列表topics爲空時該怎麼辦:這裏是打印一條消息,告訴用戶尚未添加任何主題。最後兩行分別結束for循 環和項目列表。
如今須要修改父模板base.html,使其包含到顯示全部主題的頁面的連接:
<p> <a href="{% url 'learning_logs:index' %}">Learning Log</a> - <a href="{% url 'learning_logs:topics' %}">Topics</a> </p> {% block content %}{% endblock content %}
咱們在到主頁的連接後面添加了一個連字符,而後添加了一個到顯示全部主題的頁面的連接——使用的也是模板標籤url 。這一行讓Django生成一個連接,它 與learning_logs/ urls.py中名爲topics 的URL模式匹配。
如今若是你刷新瀏覽器中的主頁,將看到連接Topics。單擊這個連接,將看到相似於圖18-4所示的網頁。
一、URL模式
顯示特定主題的頁面的URL模式與前面的全部URL模式都稍有不一樣,由於它將使用主題的id 屬性來指出請求的是哪一個主題。例如,若是用戶要查看主題Chess(其id 爲1)的詳細頁面,URL將爲http://localhost:8000/topics/1/。下面是與這個URL匹配的模式,它包含在learning_logs/urls.py中:
"""定義learning_logs的URL模式""" from django.conf.urls import url from . import views app_name='learning_logs' urlpatterns = [ # 主頁 url(r'^$', views.index, name='index'), # 顯示全部的主題 url(r'^topics/$', views.topics, name='topics'), # 制定主題的詳細頁面 url(r'^topics/(?P<topic_id>\d+)/$', views.topic, name='topic') ]
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 的值來獲取相應的主 題。
二、視圖
函數topic() 須要從數據庫中獲取指定的主題以及與之相關聯的全部條目,以下所示:
from django.shortcuts import render from .models import Topic def index(request): """學習筆記的主頁""" return render(request, 'learning_logs/index.html') def topics(request): """顯示全部的主題""" topics = Topic.objects.order_by('date_added') context = {'topics': topics} return render(request, 'learning_logs/topics.html', context) 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> <p>{{ entry.text|linebreaks }}</p> </li> {% empty %} <li> There are no entries for this topic yet. </li> {% endfor %} </ul> {% endblock content %}
像這個項目的其餘頁面同樣,這裏也繼承了base.html。接下來,咱們顯示當前的主題,它存儲在模板變量{{ topic }}中。爲何可使用變量topic呢?由於它包含在字典context 中。接下來,咱們開始定義一個顯示每一個條目的項目列表,並像前面顯示全部主題同樣遍歷條目。
每一個項目列表項都將列出兩項信息:條目的時間戳和完整的文本。爲列出時間戳,咱們顯示屬性date_added 的值。在Django模板中,豎線(| )表示模板過濾器—— 對模板變量的值進行修改的函數。過濾器date: 'M d, Y H:i'以這樣的格式顯示時間戳:January1,2015 23:00。接下來的一行顯示text的完整值,而不只僅是entry的前 50個字符。過濾器linebreaks將包含換行符的長條目轉換爲瀏覽器可以理解的格式,以避免顯示爲一個不間斷的文本塊。咱們使用模板標籤{% empty %}打 印一條消息,告訴用戶當前主題尚未條目。
(4) 將顯示全部主題的頁面中的每一個主題都設置爲連接
在瀏覽器中查看顯示特定主題的頁面前,咱們須要修改模板topics.html,讓每一個主題都連接到相應的網頁,以下所示:
{% extends "learning_logs/base.html" %} {% block content %} <p>Topics</p> <ul> {% for topic in topics %} <li> <a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a> </li> {% empty %} <li>No topics have been added yet.</li> {% endfor %} </ul> {% endblock content %}
咱們使用模板標籤url 根據learning_logs中名爲topic 的URL模式來生成合適的連接。這個URL模式要求提供實參topic_id ,所以咱們在模板標籤url 中添加了屬性topic.id 。如今,主題列表中的每一個主題都是一個連接,連接到顯示相應主題的頁面,如http://localhost:8000/topics/1/。
若是你刷新顯示全部主題的頁面,再單擊其中的一個主題,將看到相似於圖18-5所示的頁面。
參考資料:
一、python編程,從入門到實踐