【Django】(4)建立其他頁面
建立完了網站的主頁後,我們將建立兩個顯示資料的網頁,一個列出所有的主題,另一個顯示特定主題的所有條目。對於每個網頁,都要指定其URL模式,編寫一個檢視函式,一個模板。這樣做之前,可以先編寫一個父模板,讓專案中的其他模板都繼承它。
1.模板繼承
1-1.父模板
先建立一個base.html的模板,並將其儲存在index.html 所在的目錄中。base.html 包含所有頁面都有的元素,其他模板都繼承base.html。
base.html:
<p> <a href="{% url 'learning_logs:index' %}">learning_logs</a> </p> {% block content %} {% endblock content %}
其中{%%}是模板標籤,href中的learning_logs:index生成一個URL,該URL與learning_logs/urls.py中定義的名為index的URL模式匹配。
其中learning_logs是一個名稱空間,而index是該名稱空間中的一個名稱獨特的URL模式匹配。
content為佔位符,其中的資訊由子模版來指定。子模版並非必須定義父模板中的每個塊,因此在父模板中可使用任意多個content來預留空間,而子模版可根據需要定義相應數量的塊。
1-2.子模版
現在需要重新編寫index.html,使其繼承base.html,如下所示:
index.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 %}
修改為如上,在塊中填入HTML程式碼。這種繼承的方式的好處是,當網頁多了起來,管理的時候方便了許多。
2.顯示所有主題的頁面
2-1 URL模式
定義一個用來顯示所有主題的主題的頁面URL。http://localhost:8000/topics將返回顯示所有主題的條目。
先修改learning_logs/urls.py:
urls.py
"""learing_logs應用程式中的URL模式""" from django.conf.urls import url from . import views urlpatterns = [ #主頁 url(r'^$', views.index, name='index'), #顯示所有的主題 url(r'^topics/$',views.topics,name='topics'), ] app_name = 'learning_logs' #自定義的應用程式的名字
在這裡可以比較顯示主頁的程式碼,呼叫的檢視函式不一樣,前面呼叫views中的index,後者呼叫了views中的topics。
2-2.檢視
還未在views.py中新增topics,所以現在來新增views.py中的程式碼。
from django.shortcuts import render from .models import Topic #使用到資料庫時需要匯入 # Create your views here. def index(request): #省略 def topics(request): topics = Topic.objects.order_by('data_added') context = {'topics': topics} return render(request, 'learning_logs/topics.html', context)
一定從model中匯入Topic函式
2-3.模板
在index.html的同一目錄下,新建一個topics.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 %}
其中的{% for item in list %} do somethong with each item {% endfor %} 在這個迴圈中,要將每個主題轉化為一個專案列表項。要在模板中打印出變數,需要將變數名用雙花括號括起來。每次迴圈時,程式碼
{{topic}}都將被替換為當前的topic的值
{% empty % } 告訴Django在列表為空時該如何處理。
現在需要修改父模板,使其包含到顯示所有主題(topics.html)的頁面的連結
<p> <a href="{% url 'learning_logs:index' %}">learning_logs</a> <a href="{% url 'learning_logs:topics' %}">topics</a> </p> {% block content %} {% endblock content %}
3.顯示特定主題的頁面
現在需要建立一個專注於特定主題的頁面--顯示該主題的名稱以及該主題的所有條目。同樣,將定義一個新的URL模式,編寫一個檢視並建立一個模板。還將修改顯示所有主題的頁面,讓每個專案列表項都是一個連結,單擊將顯示相應的主題的所有條目。
3-1.URL模式
它將使用主題的id屬性來指出請求的時哪個主題。例如,檢視Chess(其id為1)的詳細頁面,URL 將為http://localhost:8000/topics/1/。現在修改learning_logs/urls.py:
"""learing_logs應用程式中的URL模式""" from django.conf.urls import url from . import views urlpatterns = [ #省略 url(r'^topics/(?P<topics_id>\d+)/$',views.topic,name='topic'), ] app_name = 'learning_logs' #自定義的應用程式的名字
?P<topics_id>\d+中,\d+是匹配一個數字,將匹配到的數字存入topics_id中
3-2.檢視
#省略 def topic(request,topic_id): """顯示單個主題及其所有條目""" topic = Topic.objects.get(id=topic_id) entries = topic.entry_set.order_by('-date_added') context = {'topic':topic,'entires':entries} return render(request, 'learning_logs/topic.html',context)
3-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 %}
為了將每個條目變成連結,還需要修改topics.html中的for迴圈:
{% 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 %}
如不成功,檢查程式碼。
親測效果如下: