Django中DetailView结合FormMixin用法?能否直接重写post方法?
Django DetailView中直接重写post方法简化表单实现可行吗?
当然可以!完全不需要用多个类包装的方式,直接在DetailView里重写post方法就能把表单处理逻辑合并到一个类中,大幅简化代码。
原实现代码:
from django.views import View from django.views.generic.detail import DetailView from django.views.generic.edit import SingleObjectMixin, FormView from django.urls import reverse from .models import Article from .forms import CommentForm class CommentGet(DetailView): model = Article template_name = "article_detail.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["form"] = CommentForm() return context class CommentPost(SingleObjectMixin, FormView): model = Article form_class = CommentForm template_name = "article_detail.html" def post(self, request, *args, **kwargs): self.object = self.get_object() return super().post(request, *args, **kwargs) def form_valid(self, form): comment = form.save(commit=False) comment.article = self.object comment.save() return super().form_valid(form) def get_success_url(self): article = self.get_object() return reverse("article_detail", kwargs={"pk": article.pk}) class CView(View): def get(self, request, *args, **kwargs): view = CommentGet.as_view() return view(request, *args, **kwargs) def post(self, request, *args, **kwargs): view = CommentPost.as_view() return view(request, *args, **kwargs)
简化后的完整实现:
from django.views.generic.detail import DetailView from django.shortcuts import redirect from django.urls import reverse from .models import Article from .forms import CommentForm class ArticleDetailView(DetailView): model = Article template_name = "article_detail.html" # 把评论表单传入模板上下文,和原逻辑一致 def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["form"] = CommentForm() return context # 重写post方法处理表单提交 def post(self, request, *args, **kwargs): # 获取当前文章对象 self.object = self.get_object() # 用POST数据实例化表单 form = CommentForm(request.POST) if form.is_valid(): # 创建评论但暂不提交到数据库 comment = form.save(commit=False) # 关联当前文章 comment.article = self.object comment.save() # 提交成功后重定向回文章详情页 return redirect(reverse("article_detail", kwargs={"pk": self.object.pk})) # 表单验证失败时,把错误表单放回上下文,重新渲染页面 context = self.get_context_data(**kwargs) context["form"] = form return self.render_to_response(context)
简化逻辑说明:
- 保留
get_context_data方法来给模板传递空表单,保证GET请求时页面正常渲染表单 - 重写
post方法统一处理表单提交:- 先拿到当前文章对象,和原
CommentPost类的逻辑一致 - 验证表单数据,通过就创建关联文章的评论并保存
- 验证失败时,把带错误信息的表单放回上下文,用户能在原页面看到错误提示
- 先拿到当前文章对象,和原
- 整个逻辑都集中在一个类里,不需要再做视图转发,代码更简洁易维护
内容的提问来源于stack exchange,提问作者aaaa
相关产品推荐
相关产品推荐

