iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 25
0

模板的繼承

我們可以編寫一個含有通用元素的基底模板,而不要直接在每個頁面中重複寫入這些通用元素

父模板

我們會建立一個base.html並存在跟index.html同一個資料夾內,這個檔案會有所有頁面都需要的通用元素,其他模板也都繼承自base.html,如下

<p>
   <a href="{% url 'learning_logs:index' %}">Learning Log</a>
</p>

{% block content %}{% endblock %}

上面程式碼第二行{% url 'learning_logs:index' %}會生成一個URL,此URL與learning_logs/urls.py中定義名為index的URL模式比對符合,在第五行插入一對block標記,此區塊名稱叫content,是個佔位用的符號,含有的資訊會椅子模板定義

子模板

現在我們需要重新編寫index.html檔讓他繼承自base.html,如下

{% extends "learning_logs/base.html" %}

{% block content %}
<p>hello,this is weiting's learning_log</p>
{% endblock content %}

上面程式碼第一行是在說子模板第一行要有{% extends %}標記,讓Django知道是繼承哪個父模板,第三行插入{% block %}標記來定義content區塊,是將我們在learning log的文字段落插入至content

主題&個別主題的頁面

URL模式

首先要來修改learning_logs資料夾裡的urls.py檔,如下

from django.conf.urls import url
from django.urls import path

from . import views
app_name='learning_logs'
urlpatterns=[
    path('',views.index,name='index'),
    # 顯示所有主題
    path('topics/',views.topics,name='topics'),
    # 顯示個別主題
    path('<int:topic_id>/',views.topic,name='topic'),
]

上面程式碼第九行我們在正規表示式中加了topic/字樣,當Django在檢測請求URL時,符合比對的URL請求會被傳到views.py中的topic函式處理

上面程式碼第十二行和第九行不同的地方是多了topic_id,當使用者要看MIIA主題(id 為 1)的詳細內容介面,Django會呼叫topic視圖函式,把存放在topic_id中的值當成引數傳給它,然後依照topic_id的值來取得對應的值

視圖

from django.shortcuts import render

from .models import Topic # 匯入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)

# 顯示個別主題和它的entries
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)

上面程式碼第九行topic()函式需要一個參數,Django從伺服器收到的request物件,第十行是查詢資料庫請求Topic物件,並按照date_added屬性對它們排序,第十一行是定義一個模板傳送到context字典,第十二行是除了request物件和模板路徑之外,還要把context變數給render()

顯示個別主題是從第十五行開始,第十五行除了request物建之外還需要參數的是圖函式,此函式取得topic_id的值再存到topic_id中,第十六行是用get()函式用id來取得指定主題

模板

  • 顯示全部主題的模板

顯示所有主題頁面的模板會收到context字典,所以能使用topic()所提供的資料,我們要建立一個topics.html檔,一樣存在跟index.html同一個資料夾中,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 %}

上面程式碼就像index.html模板一樣,會先用{%extends%}繼承base.html,再定義content區塊,第八行的for topic in topics就是遍訪context字典中的topics串列,每個for迴圈都要有像第十四行的{%endfor%},我們主題清單都會有一個連結,第十行的連結就是連結顯示對應特定主題的內容

Topics連結點進去的畫面如下

  • 顯示個別主題和其內容的模板
{% 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 %}

上面程式碼是我們要再創一個topic.html模板,也是以base.html為基底擴充,第五行是創一個Topic變數來存放context字典,隨後我們定義了顯示項目的清單,第十一行會顯示日期時間,第十二行是確保格式有換行符號的長紀錄項目,且能讓瀏覽器解讀,以免顯示出沒有斷行超出畫面的文字區塊

點按MIIA主題時可看到其內容的畫面如下

附上排版較精美的
HackMD網址:https://hackmd.io/2M04zx0LQDuMSNXhd10Erg?both

今天結束,各位明天見


資料來源:<<python程式設計的樂趣>>-Eric Matthes著/H&C譯
資料來源:https://blog.csdn.net/qq_28709643/article/details/79826737
資料來源:https://stackoverflow.com/questions/47661536/django-2-0-path-error-2-0-w001-has-a-route-that-contains-p-begins-wit?noredirect=1&lq=1
資料來源:https://tw.saowen.com/a/f0f2e43b86c65053ecd39c6a4c8171b09c98c65f6ded12f6d89c541190a5de02


上一篇
DAY 24 Django製作網頁
下一篇
DAY 26 Django允許使用者輸入資料
系列文
初學者Python的應用實作30

尚未有邦友留言

立即登入留言