使用 Django 的模型,都是 django.db.models.Model 类的子类。
在 论坛的回帖模型中,related_name = "+",不需要这种反向关系,不需要关系用户修改过哪些帖子。
from django.shortcuts import render, get_object_or_404, redirect, reverse
from django.contrib.auth.decorators import login_required
from django.views.generic import UpdateView, ListView
from django.utils import timezone
from django.utils.decorators import method_decorator
from django.db.models import Count
from .forms import NewTopicForm, PostForm
from .models import Board, Topic, Post
① 主题回复
class PostListView(ListView):
model = Post
context_object_name = 'posts'
template_name = 'board/topic_posts.html'
# 主题回复列表, 复用分页组件
paginate_by = 20
def get_context_data(self, **kwargs):
# 防止相同用户刷新页面被统计为多次访问 ,使用 会话 sessions
session_key = 'viewed_topic_{}'.format(self.topic.pk)
if not self.request.session.get(session_key, False):
self.topic.views += 1
self.topic.save()
self.request.session[session_key] = True
kwargs['topic'] = self.topic
return super().get_context_data(**kwargs)
def get_queryset(self):
self.topic = get_object_or_404(Topic, board__pk=self.kwargs.get('pk'), pk=self.kwargs.get('topic_pk'))
queryset = self.topic.posts.order_by('created_at')
return queryset
② 回帖
@login_required
def reply_topic(request, pk, topic_pk):
topic = get_object_or_404(Topic, board__pk=pk, pk=topic_pk)
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.topic = topic
post.created_by = request.user
post.save()
# 更新回复帖子的时间
topic.last_updated = timezone.now()
topic.save()
# 回复帖子 重定向到本页
topic_url = reverse('users:new_posts', kwargs={"pk": pk, "topic_pk": topic_pk})
topic_post_url = '{url}?page={page}#{id}'.format(
url=topic_url,
id=post.pk,
page=topic.get_page_count()
)
return redirect(topic_post_url)
else:
form = PostForm()
return render(request, 'board/reply_topic.html', {"topic": topic, "form": form})
③ 编辑帖子
@method_decorator(login_required, name='dispatch')
class PostUpdateView(UpdateView):
model = Post
fields = ('message',)
template_name = 'board/edit_post.html'
pk_url_kwarg = 'post_pk'
context_object_name = 'post'
# 其他用户可以编辑所有帖子的问题
def get_queryset(self):
queryset = super().get_queryset()
return queryset.filter(created_by=self.request.user)
def form_valid(self, form):
post = form.save(commit=False)
post.updated_by = self.request.user
post.updated_at = timezone.now()
post.save()
return redirect("users:new_posts", pk=post.topic.board.pk, topic_pk=post.topic.pk)