Django提交评论失败:IntegrityError(post_id非空约束报错)
解决Django评论存入数据库的IntegrityError问题
错误原因
IntegrityError: NOT NULL constraint failed: core_comment.post_id 是因为Comment模型的post字段为必填外键,但创建Comment对象时未传入关联的Post实例,导致数据库post_id字段为空,违反了非空约束。
修复步骤
1. 修改前端表单,传递对应Post的ID
在评论表单中添加隐藏字段,将当前帖子的ID传递到后端:
<!-- Comment section --> <form action="add-comment" method="POST" enctype="multipart/form-data"> {% csrf_token %} <!-- 添加隐藏字段传递post_id --> <input type="hidden" name="post_id" value="{{ post.id }}"> <div> <!-- Comment section typing box --> <div class="bg-gray-100 bg-gray-100 rounded-full rounded-md relative "> <input type="text" placeholder="post a comment" class="bg-transparent max-h-10 shadow-none" name="comment" id="comment"> <div class="absolute bottom-0 flex h-full items-center right-0 right-3 text-xl space-x-2"> <button class="button bg-blue-700" type="submit">submit</button> </div> </div> </form>
2. 修改视图函数,关联Post对象并创建Comment
在add_comment视图中,获取前端传递的post_id,查询对应的Post实例,创建Comment时关联该实例:
from django.shortcuts import get_object_or_404 from .models import Post, Comment @login_required(login_url='signin') def add_comment(request): if request.method == 'POST': user = request.user.username comment_body = request.POST['comment'] # 获取前端传递的post_id post_id = request.POST.get('post_id') # 找到对应的Post对象,不存在则返回404 post = get_object_or_404(Post, id=post_id) # 创建Comment时关联post字段 Comment.objects.create( post=post, name=user, body=comment_body ) # create方法自动保存,无需额外调用save() # 建议重定向回原帖子页面,优化用户体验 return redirect('/') # 可替换为对应帖子详情页的URL else: return redirect('/')
可选优化:通过URL传递post_id
如果调整URL配置为带参数的形式(如path('add-comment/<uuid:post_id>/', views.add_comment, name='add-comment')),可以通过URL传递post_id:
- 前端表单
action改为:{% url 'add-comment' post.id %} - 视图修改为:
@login_required(login_url='signin') def add_comment(request, post_id): if request.method == 'POST': user = request.user.username comment_body = request.POST['comment'] post = get_object_or_404(Post, id=post_id) Comment.objects.create( post=post, name=user, body=comment_body ) return redirect('/') else: return redirect('/')
内容的提问来源于stack exchange,提问作者San07
相关产品推荐
相关产品推荐

