主題計數器
為了解各討論主題的熱門程度,可以記錄每個討論主題的瀏覽人次。
修改資料模型
首先開啟 forum/topic/models.py
,修改 Topic
這個 資料模型的類別,插入第 13 行來新增一個整數欄位,用以記錄瀏覽次數:
class Topic(models.Model):
subject = models.CharField('討論主題', max_length=255)
content = models.TextField('內文')
author = models.ForeignKey(User, models.CASCADE)
created = models.DateTimeField('建立時間', auto_now_add=True)
replied = models.DateTimeField('回覆時間', null=True, blank=True)
hits = models.IntegerField('瀏覽次數', default=0)
def __str__(self):
return "{}: {}".format(self.author, self.subject)
在變更過資料模型的欄位定義之後,要記得對資料庫進行更新,請在終端機執行以下指令:
python manage.py makemigrations
python manage.py migrate
修改處理視圖
開啟 forum/topic/views.py
,修改 TopicView
視圖類別的內容:
class TopicView(DetailView):
model = Topic
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx['reply_list'] = Reply.objects.filter(topic=self.object)
return ctx
def get_object(self):
topic = super().get_object()
topic.hits += 1
topic.save()
return topic
修改討論主題列表頁面範本
修改 forum/pagetmpl/topic/topic_list.html
,插入第 11, 23 - 25 行,在表格中新增瀏覽次數的欄位:
{% extends "base.html" %}
{% block content %}
<table class="table table-sm">
<thead>
<tr class="text-light bg-dark">
<th>發起時間</th>
<th>討論主題</th>
<th>發起人</th>
<th>回覆時間</th>
<th>人氣</th>
</tr>
</thead>
<tbody>
{% for topic in topic_list %}
<tr>
<td>{{ topic.created|date:"Y/m/d H:i" }}</td>
<td>
<a href="{% url 'topic_view' topic.id %}">{{ topic.subject }}</a>
</td>
<td>{{ topic.author }}</td>
<td>{{ topic.replied|date:"Y/m/d H:i" }}</td>
<td>
<span class="badge badge-primary">{{ topic.hits }}</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% include "pagination.html" %}
{% endblock %}
ForeignKey 外(來)鍵的特異功能
在定義資料模型時,若有使用 ForeignKey
型態的欄位,被該欄位參考的資料模型可以自動取得參考它的紀錄組(queryset),不需手動篩選紀錄後再進行處理。以本案例來說,資料模型 Reply
的 topic
欄位為參考資料模型 Topic
的 ForeignKey
型態,因此 Django 會自動在資料模型 Topic
裡新增一個名為 reply_set
的屬性,用以表示參考某一筆討論主題(Topic
)的回覆意見(Reply
)的紀錄組,可以取得與討論主題相關的回覆意見的所有紀錄。
加入回覆次數的資訊
若要在討論主題列表的頁面顯示該主題有多少篇回覆意見的話,不需要像記錄瀏覽次數一樣,在資料模型 Topic
底下新增一個欄位來儲存這個資訊。利用 Django 對 ForeignKey
型態欄位的處理方式,在視圖中可以透過 reply_set.count()
來取得紀錄的數量。
所以不需要修改資料模型,也不用變更處理視圖的定義,直接修改討論主題列表的頁面範本就可以了。
開啟 forum/pagetmpl/topic/topic_list.html
,將內容修改如下:
{% extends "base.html" %}
{% block content %}
<table class="table table-sm">
<thead>
<tr class="text-light bg-dark">
<th>發起時間</th>
<th>討論主題</th>
<th>發起人</th>
<th>回覆時間</th>
<th>人氣</th>
</tr>
</thead>
<tbody>
{% for topic in topic_list %}
<tr>
<td>{{ topic.created|date:"Y/m/d H:i" }}</td>
<td>
<a href="{% url 'topic_view' topic.id %}">{{ topic.subject }}</a>
</td>
<td>{{ topic.author }}</td>
<td>{{ topic.replied|date:"Y/m/d H:i" }}</td>
<td>
<span class="badge badge-primary">{{ topic.hits }}</span>
<span class="badge badge-danger">{{ topic.reply_set.count }}</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% include "pagination.html" %}
{% endblock %}
簡化討論主題的程式碼
由於 Django 會透過 ForeignKey
的關聯性,自動為資料模型 Topic
新增 reply_set
屬性,因此不需要自己撰寫程式碼來篩選出相關回覆意見的紀錄,再傳遞給頁面範本。
修改 forum/topic/views.py
,刪除 TopicView
的 get_context_data()
方法:
class TopicView(DetailView):
model = Topic
def get_object(self):
topic = super().get_object()
topic.hits += 1
topic.save()
return topic
接著同步調整一下檢視討論主題的頁面範本 forum/pagetmpl/topic/topic_detail.html
,修改第 26 行:
{% extends "base.html" %}
{% block content %}
<div class="card">
<div class="card-header d-md-flex justify-content-between">
<div class="h3">{{ topic.subject }}</div>
<div class="text-muted">
<small><i class="fas fa-user"></i> {{ topic.author }}</small>
<small><i class="fas fa-clock"></i> {{ topic.created|date:"Y/m/d H:i" }}</small>
</div>
</div>
<div class="card-body">
{% if perms.topic.delete_topic %}
<a href="{% url 'topic_delete' topic.id %}" class="btn btn-sm btn-danger float-right">刪除主題</a>
{% endif %}
{{ topic.content|linebreaks }}
</div>
{% if user.is_authenticated %}
<div class="card-footer">
<a href="{% url 'topic_reply' topic.id %}" class="btn btn-primary">回覆討論</a>
</div>
{% endif %}
</div>
<hr/>
<ul class="list-group">
{% for reply in topic.reply_set.all %}
<li class="list-group-item d-md-flex justify-content-between">
<div class="ml-2">{{ reply.content|linebreaks }}</div>
<small class="text-muted">
<i class="fas fa-user"></i> {{ reply.author }}
<i class="fas fa-clock"></i> {{ reply.created|date:"Y/m/d H:i" }}
{% if perms.topic.delete_reply %}
<a href="{% url 'reply_delete' reply.id %}" class="btn btn-sm btn-danger">刪除回覆</a>
{% endif %}
</small>
</li>
{% endfor %}
</ul>
{% endblock %}
主題計數器
為了解各討論主題的熱門程度,可以記錄每個討論主題的瀏覽人次。
修改資料模型
首先開啟
forum/topic/models.py
,修改Topic
這個 資料模型的類別,插入第 13 行來新增一個整數欄位,用以記錄瀏覽次數:在變更過資料模型的欄位定義之後,要記得對資料庫進行更新,請在終端機執行以下指令:
修改處理視圖
開啟
forum/topic/views.py
,修改TopicView
視圖類別的內容:修改討論主題列表頁面範本
修改
forum/pagetmpl/topic/topic_list.html
,插入第 11, 23 - 25 行,在表格中新增瀏覽次數的欄位:ForeignKey 外(來)鍵的特異功能
在定義資料模型時,若有使用
ForeignKey
型態的欄位,被該欄位參考的資料模型可以自動取得參考它的紀錄組(queryset),不需手動篩選紀錄後再進行處理。以本案例來說,資料模型Reply
的topic
欄位為參考資料模型Topic
的ForeignKey
型態,因此 Django 會自動在資料模型Topic
裡新增一個名為reply_set
的屬性,用以表示參考某一筆討論主題(Topic
)的回覆意見(Reply
)的紀錄組,可以取得與討論主題相關的回覆意見的所有紀錄。加入回覆次數的資訊
若要在討論主題列表的頁面顯示該主題有多少篇回覆意見的話,不需要像記錄瀏覽次數一樣,在資料模型
Topic
底下新增一個欄位來儲存這個資訊。利用 Django 對ForeignKey
型態欄位的處理方式,在視圖中可以透過reply_set.count()
來取得紀錄的數量。所以不需要修改資料模型,也不用變更處理視圖的定義,直接修改討論主題列表的頁面範本就可以了。
開啟
forum/pagetmpl/topic/topic_list.html
,將內容修改如下:簡化討論主題的程式碼
由於 Django 會透過
ForeignKey
的關聯性,自動為資料模型Topic
新增reply_set
屬性,因此不需要自己撰寫程式碼來篩選出相關回覆意見的紀錄,再傳遞給頁面範本。修改
forum/topic/views.py
,刪除TopicView
的get_context_data()
方法:接著同步調整一下檢視討論主題的頁面範本
forum/pagetmpl/topic/topic_detail.html
,修改第 26 行: