我正在为一个允许用户创建帖子并对这些帖子发表评论的网站使用Django Rest Framework构建API。我可以从API创建帖子,但是当我尝试创建评论时,我收到以下错误:
NOT NULL约束失败:app_comment.post_id
我的模特:
class Post(models.Model):
owner = models.ForeignKey('auth.User', related_name = 'posts')
post_title = models.CharField(max_length=200)
post_description = models.CharField(max_length=1000)
class Comment(models.Model):
user = models.ForeignKey(User, related_name = 'comments')
post = models.ForeignKey(Post, related_name = 'comments')
text = models.CharField(max_length=1000)
和我的评论序列化器:
class CommentSerializer(serializers.ModelSerializer):
user = serializers.ReadOnlyField(source='user.username')
post = serializers.ReadOnlyField(source='post.id')
class Meta:
model = Comment
fields = ('id', 'text', 'user', 'post')
和我的评论观点:
class PostCommentList(generics.ListCreateAPIView):
permission_classes = (permissions.IsAuthenticated,
IsOwnerOrReadOnly,)
serializer_class = CommentSerializer
def get_queryset(self):
post = self.kwargs['post_pk']
post = Post.objects.get(pk = post)
return post.comments.all()
def perform_create(self, serializer):
post = self.kwargs['post_pk']
print("creating a comment from " + str(self.request.user) + " on post " + str(post) +" : "+ str(Post.objects.get(pk = post)))
serializer.save(user = self.request.user)
serializer.save(post = self.kwargs['post_pk'])
尝试在帖子上创建评论时,我会看到正在打印出的正确信息(即'在帖子6上创建用户评论:发布对象')。
为什么我的评论没有使用正确的post_id创建?
答案 0 :(得分:2)
在perform_create函数中,您将获得一个整数而不是Post对象的主键。此外,您不希望两次调用保存 - 这将导致保存两个模型(假设它不会抛出验证错误 - 在这种情况下就是这样)。
更好的方法可能是:
post_pk = self.kwargs['post_pk']
post = Post.objects.get(pk = post_pk)
serializer.save(user=self.request.user, post=post)
此外,您可能还希望将文本内容添加到您正在保存的模型中。所以也许,所以你可能需要添加/更改它来阅读:
text = self.kwargs['text']
serializer.save(user=self.request.user, post=post, text=text)
虽然我正在考虑这个问题 - 但您可能希望保存一个“获取”的电话。并避免访问数据库并直接指定外键。您可以使用以下语法执行此操作:
post_pk = self.kwargs['post_pk']
# Note - we won't call '.get' here
serializer.save(user=self.request.user, post_id=post_pk, text=text)
答案 1 :(得分:0)
嗯,最明显的错误是你两次调用save(),首先是用户,有一个帖子。并且在第一次调用中,它尝试创建没有帖子的注释,并使数据库为您提供失败的约束错误。替换
serializer.save(user = self.request.user) serializer.save(post = self.kwargs['post_pk'])
与
serializer.save(user=self.request.user, post=int(self.kwargs['post_pk']))
你应该没事。
那就是说,您应该删除ReadOnlyFields并将read_only_fields添加到序列化器元
class CommentSerializer(serializers.ModelSerializer): class Meta: model = Comment fields = ('id', 'text', 'user', 'post') read_only_fields = ('post', 'user')