第 9 章 顯示部落格文章
(1) 在部落格頁面顯示文章
∗ 顯示部落格文章
▸ 目前進入部落格頁面僅顯示「部落格 -- 歡迎蒞臨」等字樣,現在改為顯示部落格文章,修改 views 程式:
article/views.py
from django.shortcuts import render from article.models import Article def article(request): ''' Render the article page ''' articles = Article.objects.all() context = {'articles':articles} return render(request, 'article/article.html', context)
✶ 匯入 Article model
✶ articles = ...:利用 ORM之 查詢 (Query) 指令取出所有資料,資料型態為查詢集 (Queryset)
✶ context = ...:利用範本變數 articles 將查詢結果傳至範本
▸ 修改範本:在 content 區塊加入內容
article/templates/article/article.html
...
{% block content %}
<br>
{% for article in articles %}
<h3>{{ article.title }}</h3>
<p>發表時間:{{ article.pubDateTime|date:'Y-m-d H:i' }}</p>
<div class="articleContent">{{ article.content }}</div>
<hr>
{% endfor %}
{% endblock %}
✶ {% for article in articles %}:views 程式傳入 articles 查詢集,此迴圈針對每一筆資料進行處理,每次迴圈所使用的物件稱為 article
✶ {{ article.title }}:顯示 article 的 title 欄位內容
✶ {{ article.pubDateTime|date:'Y-m-d H:i' }}: 顯示 pubDateTime 欄位內容
# | 符號稱為過濾器 (Filter),針對資料做進一步處理
# date: 設定資料之日期顯示格式
# Y-m-d:年月日 (4 碼西元年),以短橫線連結,後接一個空白
# H:i:時分(24 時制),中間加冒號
✶ {{ article.content }}:顯示文章內容,並加上一個 articleContent 類別,方便之後的 CSS 樣式設定
✶ 測試:發現文章內容並未斷行 (HTML中,\n 並無效應)
# 加上 linebreaks:
<div class="articleContent">{{ article.content|linebreaks
}}<div>
✶ 再次測試並檢視原始碼:範本引擎將 \n 置換為 <br>, 並且將文章內容以 <p> 段落標籤包住,如下:
<h3>簡單學習Django</h3> <p>發表時間:...</p> <div class="articleContent"> <p>簡單學習Django<br> 簡單學習Django<br> 簡單學習Django<br> ... <p> <div> <hr>
∗ 加上 CSS 設定,讓文章呈現邊框及背景
▸ 首先在 base.html 中新增名為 css 之範本區塊,讓各個 App 決定是否加入各別的 CSS 連結
main/templates/main/base.html
...
<head>
<title>部落格</title>
<meta charset="utf-8">
<link rel="stylesheet" href="/static/main/css/main.css">
{% block css %}{% endblock %}
</head>
...
▸ 新增 CSS 檔案 (先建立以下目錄: article/static, article/static/article, article/static/article/css)
article/static/article/css/article.css
.articleContent { padding: 20px; background-color: #e9e9e9; border: thin solid gray; border-radius: 10px; }
▸ 在 article.html 加上 CSS 連結:
article/templates/article/article.html
{% extends 'main/base.html' %}
{% load static %}
{% block css %}
<link rel="stylesheet" href="{% static 'article/css/article.css' %}">
{% endblock %}
{% block heading %}歡迎蒞臨{% endblock %}
{% block content %}
...
{% endblock %}
✶ 只要在範本中有靜態檔案連結者,均需要加上 {% load static %}
✶ 新增 css 範本區塊,內容為 CSS 檔案之連結
▸ 測試 (可能需要重新啟動伺服器)
∗ 僅顯示文章部份內容
▸ 由於文章內容可能很長,應先顯示部份內容,訪客有興趣的話再看全部內容:利用範本過濾器 truncatechars_html 截斷文章,只顯示部份內容
{{ article.content|linebreaks|truncatechars_html:30 }}
✶ 僅顯示 30 個字元 (包含 3 個句點),其餘截斷,而且保持 HTML 標籤正確配對
→ 測試:文章內容截斷,並以 3 個句點結束
▸ 註:另有
✶ truncatechars 過濾器:不管 HTML 標籤配對
✶ truncatewords_html 過濾器:不截斷英文單字
(2) 在每篇文章下方顯示所屬留言
∗ 取出文章留言
▸ 在 views 程式中,同時取出文章與留言
article/views.py
... from article.models import Article, Comment def article(request): ''' Render the article page ''' articles = Article.objects.all() articles = {article:Comment.objects.filter(article=article) for article in Article.objects.all()} context = {'articles':articles} return render(request, 'article/article.html', context)
✶ 匯入 Comment model
✶ 將 articles 變數改為一個字典 (Dictionary),其中每個項目的鍵 (Key) 就是文章物件,而其對應值 (Value) 就是所屬的留言查詢集 (Queryset):
articles = { article1: [comment1-1, comment1-2, comment1-3, ...], article2: [comment2-1, comment2-2, comment2-3, ...], ... }
✶ 迴圈:每一篇文章迴圈產生一組字典項目
✶ 註:Python 3.6 開始,字典項目依照輸入的順序排序,因此文章還是會依照日期順序來顯示
∗ 頁面顯示文章及留言
article/templates/article/article.html
...
{% block content %}
<br>
{% for article in articles %}
...
{% endfor %}
{% for article, comments in articles.items %}
<h3>{{ article.title }}</h3>
<p>發表時間:{{ article.pubDateTime|date:'Y-m-d H:i' }}</p>
<div class="articleContent">{{ article.content|linebreaks|truncatechars_html:30 }}</div>
{% for comment in comments %}
<div class="commentDiv">
<span class="comment">{{ comment.content }}</span>
<br>
<span class="commentTime">{{ comment.pubDateTime|date:'m月d日 H:i' }}</span>
</div>
{% endfor %}
<hr>
{% endfor %}
{% endblock %}
▸ 利用 2 層巢狀迴圈顯示文章及留言,外層迴圈的每一個項目是文章,內層迴圈的每一個項目文章的所屬留言
▸ 以迴圈處理字典的範本指令格式如下:
{% for key, value in <dict>.items %} {{ key }}: {{ value }} {% endfor %}
因此,取用文章及留言的迴圈語法為 {% for article, comments in articles.items %}
▸ 每個留言設定 commentDiv, comment, commentTime 等 CSS 類別, 留言字體設定較小,日期設為灰色:
article/static/article/css/article.css
.articleContent {
...
}
.commentDiv {
margin-top: 1em;
}
.comment {
font-size: 0.8em;
}
.commentTime {
font-size: 0.6em;
color: #777777;
}