2014-08-28 201 views
3

我正在玩DRF並做了一個簡單的博客,匿名人員可以在博客文章中發表評論。我現在只是使用可瀏覽的API,並且在我嘗試發表評論之前,似乎一切正常。 DELETE,GET和PUT都按預期工作,只有POST。django rest框架中的IntegrityError

我得到的錯誤是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'), 
) 

任何幫助將不勝感激,這是推動我瘋了。

+0

你能告訴我們你在發佈什麼嗎?由於評論必須始終屬於您模型的博客帖子,因此您在創建新評論時必須提供博客帖子ID。這是什麼抱怨。 – veroxii 2014-08-28 23:35:24

+0

我在發佈作者和內容時,沒有發送博客帖子ID的選項。再次,我使用可瀏覽的API來測試一切。 ** andrean **的答案越接近,但它也不會正確設置blogpost id。 – 2014-08-29 18:54:36

回答

2

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

當你創建一個POST請求,該blogpost字段應包含博客文章的id到你安裝此評論。

+0

謝謝!那樣做了。快速問題:在發表評論的形式中,有沒有辦法讓blogpost字段不可編輯?當我在序列化程序中將其設置爲read_only = True時,我再次遇到錯誤。 – 2014-08-29 18:49:38

+0

對於發佈請求,它必須保持可編輯狀態,但可以針對不同的請求方法使用不同的序列化器。因此,例如,您可以創建一個新的'CommentUpdateSerializer',並將字段'blogpost'設爲只讀,然後在您的視圖中覆蓋'get_serializer_class'方法,檢查請求方法並返回相應的類。對於發佈請求,普通的'CommentSerializer',用於put和patch請求'CommentUpdateSerializer'類。 – andrean 2014-08-29 21:48:00