回覆討論主題

定義回覆資料模型

開啟 forum/topic/models.py,新增以下程式碼來定義回覆資料模型:

# 討論主題內的回覆 class Reply(models.Model): topic = models.ForeignKey(Topic, models.CASCADE) content = models.TextField('回覆內容') author = models.ForeignKey(User, models.CASCADE) created = models.DateTimeField('回覆時間', auto_now_add=True) def __str__(self): return "{} | {}: {}".format( self.topic, self.author, self.content )

新增路徑規則

開啟 forum/topic/urls.py,在 urlpatterns 中新增第 8 行的規則:

urlpatterns = [ path('', TopicList.as_view(), name='topic_list'), path('new/', TopicNew.as_view(), name='topic_new'), path('<int:pk>/', TopicView.as_view(), name='topic_view'), path('<int:tid>/reply/', TopicReply.as_view(), name='topic_reply'), ]

新增處理視圖類別

開啟 forum/topic/views.py 新增以下程式碼:

from datetime import datetime
# 回覆討論主題 class TopicReply(CreateView): model = Reply fields = ['content'] template_name = 'topic/topic_form.html' def form_valid(self, form): topic = Topic.objects.get(id=self.kwargs['tid']) form.instance.topic = topic form.instance.author = self.request.user topic.replied = datetime.now() # 更新討論主題回覆時間 topic.save() return super().form_valid(form) def get_success_url(self): return reverse('topic_view', args=[self.kwargs['tid']])

在檢視討論主題時,應該也要同時顯示相關的回覆紀錄,所以也需要修改同一個檔案的 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

修改頁面範本

開啟 forum/pagetmpl/topic_detail.html 修改為以下程式碼:

{% 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"> {{ 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 reply_list %} <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" }} </small> </li> {% endfor %} </ul> {% endblock %}