【问题标题】:IntegrityError in django rest frameworkDjango REST框架中的IntegrityError
【发布时间】:2014-10-22 22:38:46
【问题描述】:

我正在使用 DRF 并创建了一个简单的博客,匿名用户可以在其中评论博客文章。我现在只是在使用可浏览的 API,在我尝试发表评论之前,一切似乎都运行良好。 DELETE、GET 和 PUT 都按预期工作,只有 POST。

我得到的错误是IntegrityError at /api/posts/i-had-a-blog-his-name-was-bingo/comments/: blog_comment.blogpost_id may not be NULL

我已经彻底搜索了为什么会发生这种情况的答案,但没有任何帮助。这是我的代码...

models.py

class BlogPost(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    owner = models.ForeignKey('auth.User', related_name='posts')
    title = models.CharField(max_length=100, unique=True)
    content = models.TextField()
    slug = models.SlugField(max_length=100, unique=True, editable=False)
    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)
        super(BlogPost, self).save(*args, **kwargs)
    @permalink
    def get_absolute_url(self):
        return ('post-detail', { 'slug': self.slug })
    class Meta:
        ordering = ('created',)

class Comment(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    blogpost = models.ForeignKey(BlogPost, related_name='comments')
    author = models.CharField(max_length=100, blank=False)
    content = models.TextField()
    class Meta:
        ordering = ('created', 'author', 'content')

serializers.py

class CommentSerializer(serializers.HyperlinkedModelSerializer):
    post = serializers.Field(source='blogpost.title')

    class Meta:
        model = Comment
        fields = ('id', 'author', 'content', 'post')    


class BlogPostSerializer(serializers.HyperlinkedModelSerializer):
    owner = serializers.Field(source='owner.username')
    url = serializers.HyperlinkedIdentityField(view_name='post-detail')
    comments = serializers.HyperlinkedIdentityField(view_name='comment-list')

    class Meta:
        model = BlogPost
        fields = ('url', 'id', 'title', 'content', 'owner', 'comments')

views.py

class CommentList(generics.ListCreateAPIView):
    serializer_class = CommentSerializer

    def get_queryset(self):
        slug = self.kwargs['slug']
        return Comment.objects.filter(blogpost__slug=slug)


class CommentDetail(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = CommentSerializer
    permission_classes = (IsAdminOrNoEdit,)

    def get_queryset(self):
        slug = self.kwargs['slug']
        return Comment.objects.filter(blogpost__slug=slug)

urls.py

commentpatterns = patterns('',
    url(r'^$', views.CommentList.as_view(), name='comment-list'),
    url(r'^(?P<pk>[0-9]+)/$', views.CommentDetail.as_view(), name='comment-detail'),
)


urlpatterns = patterns('blog.views',
    url(r'^$', 'api_root'),
    url(r'^posts/$', views.PostList.as_view(), name='post-list'),
    url(r'^posts/(?P<slug>[-\w]+)/$', views.PostDetail.as_view(), name='post-detail'),
    url(r'^posts/(?P<slug>[-\w]+)/comments/', include(commentpatterns)),
    url(r'^users/$', views.UserList.as_view(), name='user-list'),
    url(r'^users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view(), name='user-detail'),
)

任何帮助将不胜感激,这让我发疯了。

【问题讨论】:

  • 你能告诉我们你在发布什么吗?由于评论始终必须属于模型中的博文,因此您必须在创建新评论时提供博文 ID。这就是它所抱怨的。
  • 我发布了作者和内容,没有发送博文ID的选项。同样,我正在使用可浏览的 API 来测试所有内容。 andrean 的回答让我离我更近了,但它没有正确设置博文 ID。

标签: python django django-rest-framework


【解决方案1】:

你的Comment模型定义了一个ForeignKey,不允许是null

class Comment(models.Model):
    ...
    blogpost = models.ForeignKey(BlogPost, related_name='comments')
    ...

没关系,但是您的序列化程序不包含blogpost id,因此即使您的请求包含它,它也会被忽略。更正您的序列化程序以包含 blogpost 字段:

class CommentSerializer(serializers.HyperlinkedModelSerializer):
    post = serializers.Field(source='blogpost.title')
    blogpost = serializers.PrimaryKeyRelatedField()

    class Meta:
        model = Comment
        fields = ('id', 'author', 'content', 'post', 'blogpost')

现在,当您创建帖子请求时,blogpost 字段应包含您要附加​​此评论的博客帖子的 id

【讨论】:

  • 谢谢!做到了。小问题:在发表评论的表单中,有没有办法使 blogpost 字段不可编辑?当我在序列化程序中将其设置为 read_only=True 时,我再次收到错误。
  • 对于发布请求,它必须保持可编辑状态,但您可以为不同的请求方法使用不同的序列化程序。因此,例如,您可以创建一个新的CommentUpdateSerializer 字段blogpost 为只读,然后在您的视图中覆盖get_serializer_class 方法,检查请求方法,并返回适当的类。对于 post 请求,普通的 CommentSerializer,对于 put 和 patch 请求,CommentUpdateSerializer 类。
猜你喜欢
  • 1970-01-01
  • 2016-08-10
  • 1970-01-01
  • 2017-04-01
  • 1970-01-01
  • 2020-07-31
  • 2015-10-19
  • 2017-11-09
  • 2018-03-01
相关资源
最近更新 更多