Django DetailView集成FormMixin添加评论提交后无法存储问题
问题根因
你提交的评论无法存储是两个核心问题导致的:
- 表单未提交
post字段值:你在表单配置中声明了要包含post字段,但前端只渲染了body输入框,post值没有随请求提交,表单校验不通过无法保存 - 未给评论的
author字段赋值:PostComment模型存在必填的author外键字段,你在保存表单时没有绑定当前登录用户,数据不符合字段约束无法入库
具体修改步骤
- 修改forms.py,移除不需要前端提交的字段
把CommentForm的Meta配置中post字段删掉,避免前端漏传的问题,也能防止恶意用户提交其他文章的评论:
class Meta: model = PostComment fields = ['body',]
- 修改views.py的form_valid方法,手动绑定关联字段
保存表单前先不提交到数据库,手动给评论实例绑定当前文章和登录用户:
def form_valid(self, form): # 先构造评论实例但不入库 comment = form.save(commit=False) # 绑定当前访问的帖子 comment.post = self.object # 绑定当前登录的评论作者 comment.author = self.request.user # 正式保存到数据库 comment.save() return super(PostDetailView, self).form_valid(form)
(可选优化)删除模板中多余的csrf_token
crispy表单渲染时会自动生成csrf_token输入框,你在{% crispy form %}外面单独写的{% csrf_token %}没有作用,可以直接删掉。(可选调试)添加表单错误提示
如果后续还有问题,可以在模板的表单位置上方添加错误提示,方便定位问题:
{% if form.errors %} <div class="alert alert-danger"> {% for field in form %} {% for error in field.errors %} <p>{{ field.label }}: {{ error }}</p> {% endfor %} {% endfor %} {% for error in form.non_field_errors %} <p>{{ error }}</p> {% endfor %} </div> {% endif %} {% crispy form %}
补充说明:如果你的站点允许未登录用户评论,需要额外处理author字段的逻辑,比如改成允许为空或者关联匿名用户表,否则未登录用户提交评论会报错。
内容的提问来源于stack exchange,提问作者Python Student
相关产品推荐
相关产品推荐

