Django博客基于slug实现评论功能报post_id非空约束错误
报错原因
form.instance.post__slug = self.kwargs["slug"]是错误写法。Django ORM里双下划线跨表的语法只适用于查询场景(比如Comment.objects.filter(post__slug="xxx")),不能直接用来给模型实例的关联字段赋值。
之前用主键关联时form.instance.post_id = self.kwargs['pk']能生效,是因为ForeignKey字段在数据库中会自动生成名为外键名_id的列,存储关联对象的主键值,直接给这个字段传主键ID是合法操作。但slug不是Post模型的主键,Comment表中不存在对应存储post slug的字段,框架也不会自动根据你传入的slug反查Post对象填充必填的post_id,最终保存Comment实例时post_id为空,就触发了非空约束报错。
修复方案
先通过URL传过来的slug查询到对应的博文对象,再把这个对象赋值给评论实例的post外键字段即可。
首先在views.py文件顶部导入需要的工具方法:
from django.shortcuts import get_object_or_404
然后修改类视图中的form_valid方法:
class AddCommentView(CreateView): model = Comment form_class = AddCommentForm template_name = "add_comment.html" def form_valid(self, form): # 根据slug匹配对应博文,匹配不到直接返回404 post = get_object_or_404(Post, slug=self.kwargs["slug"]) form.instance.post = post form.instance.name = self.request.user return super().form_valid(form)
优化建议
- 目前Post模型的slug字段设置了
null=True, blank=True,且是保存时根据标题自动生成,建议给slug字段加上unique=True约束,避免同名博文生成重复slug导致查询出错。 - 检查路由配置,确认访问添加评论页面的路径中携带了post的slug参数,且参数名和
self.kwargs里取的键名一致。
内容的提问来源于stack exchange,提问作者Ekansh Virmani
相关产品推荐
相关产品推荐

