Django中使用CreateView传递数据报错:NOT NULL约束失败
解决Django CreateView评论关联影片和用户的NOT NULL约束错误
这个错误NOT NULL constraint failed: films_comment.film_id其实很好理解——你的Comment模型里film和user都是必填的外键字段,但当前的CommentCreate视图只处理了body输入框的内容,完全没给这两个必填字段赋值,数据库自然会报错。下面一步步来修复:
1. 修改CommentCreate视图,手动关联用户和影片
我们需要重写CreateView的form_valid方法,在表单保存前把当前用户和目标影片绑定到评论对象上,同时还要确保只有登录用户才能评论:
from django.views.generic.edit import CreateView from django.contrib.auth.mixins import LoginRequiredMixin from .models import Film, Comment class CommentCreate(LoginRequiredMixin, CreateView): model = Comment fields = ['body'] def form_valid(self, form): # 从URL参数里拿到影片ID,找到对应的影片对象 target_film = Film.objects.get(pk=self.kwargs['film_id']) # 给评论对象绑定当前登录用户和目标影片 form.instance.user = self.request.user form.instance.film = target_film # 调用父类方法完成保存 return super().form_valid(form) def get_success_url(self): # 评论提交后跳回对应的影片详情页 return self.object.film.get_absolute_url()
关键说明:
LoginRequiredMixin:强制用户登录才能进入评论页面,避免user字段为空的情况。self.kwargs['film_id']:从你配置的URL里提取传递过来的影片ID,精准找到要评论的影片。form.instance.user/film:在表单保存到数据库前,手动给这两个必填外键字段赋值,绕开前端表单的输入要求。
2. 可选:给Comment模型添加跳转逻辑
如果不想在视图里写get_success_url,可以给Comment模型加一个get_absolute_url方法,CreateView会自动用它来做跳转:
class Comment(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) film = models.ForeignKey(Film, on_delete=models.CASCADE) body = models.CharField(max_length=200) def get_absolute_url(self): # 评论提交后直接跳回所属影片的详情页 return self.film.get_absolute_url()
3. 确认现有配置没问题
你的URL规则、详情页的评论链接、表单模板都是正确的:
- URL里的
<int:film_id>能正确接收影片ID - 详情页的
{% url 'films:add_comment' film_id=film.id %}能正确传递参数 - 表单只需要显示
body字段,其他字段在后台自动赋值,不需要用户输入
这样修改后,再提交评论时,系统会自动把当前用户和目标影片关联到新评论上,就不会再触发NOT NULL约束错误了。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

