简体   繁体   中英

IntegrityError in django rest framework

I'm playing with DRF and made a simple blog where anonymous people can comment on a blog post. I'm just using the browsable API at the moment, and everything seems to work fine until I try to post a comment. DELETE, GET, and PUT all work as expected, only POST.

The error I get is IntegrityError at /api/posts/i-had-a-blog-his-name-was-bingo/comments/: blog_comment.blogpost_id may not be NULL

I've searched thoroughly for an answer as to why this might be happening, but nothing is helping. Here's my code...

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'),
)

Any help would be greatly appreciated, this is driving me crazy.

Your Comment model defines a ForeignKey , which is not allowed to be null :

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

which is ok, but your serializer does not include the blogpost id, so even if your request includes it, it will be just ignored. correct your serializer to include the blogpost field:

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

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

now when you create a post request, the blogpost field should contain the id of the blog post to which you're attaching this comment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM