Django创建评论报错:Comment.comment_user需为Profile实例如何解决
问题根因
报错的核心原因是字段赋值类型不匹配:
Comment模型的comment_user字段外键关联的是Profile表,要求赋值必须是Profile类的实例- 你在
serializer.save里传入的self.request.user是Django自带的User表实例,和要求的类型不符,所以触发了赋值错误。
修复步骤
1. 获取当前登录用户对应的Profile实例
你在Profile模型的name字段中设置了和User的一对一关联,反向关联名是user,所以可以直接通过request.user.user拿到当前用户对应的Profile实例。
2. 简化重复评论校验逻辑
直接用Profile实例做过滤条件,不需要跨表查询用户名,执行效率更高。
3. 修正save方法的传参
把comment_user参数替换为获取到的Profile实例即可。
修复后的views.py代码如下:
class CommentCreateApiView(generics.CreateAPIView): serializer_class = CommentSerializer #permission_classes = [TodoCreatorOrReadOnly] # def get_queryset(self): # return Comment.objects.all() def perform_create(self, serializer): todo_id = self.kwargs['todo_id'] todo_item = Todo.objects.get(pk=todo_id) # 获取当前用户对应的Profile实例 current_user_profile = self.request.user.user # 校验是否已提交过评论 comment_exists = Comment.objects.filter(todo=todo_item, comment_user=current_user_profile).exists() if comment_exists: raise ValidationError('你已经对该待办事项提交过评论了') # 传入正确类型的实例保存 serializer.save(todo=todo_item, comment_user=current_user_profile)
额外优化建议
建议给Comment模型增加联合唯一约束,从数据库层面兜底防止重复评论,即使业务逻辑校验被绕过也不会产生脏数据,在Comment模型中添加如下代码即可:
class Comment(models.Model): # 原有字段保持不变 class Meta: constraints = [ models.UniqueConstraint(fields=['comment_user', 'todo'], name='unique_user_todo_comment') ]
另外要确保每个User创建时都自动生成关联的Profile实例,否则调用request.user.user会抛出关联对象不存在的错误,可以通过Django信号实现该逻辑。
内容的提问来源于stack exchange,提问作者Md.Shakil Shaikh
相关产品推荐
相关产品推荐

