2013-04-08 34 views
8

我正在使用Django REST框架爲我的web應用程序創建一個API。我有一堂課'評論',其中depth=2設置在Meta班。這在GET ing Comments時很好用。當我嘗試發送POSTPUT請求時(即創建新的Comment),我被告知需要包含對象而不是ForeignKey ID。Django REST框架POST/PUT的不同深度?

這裏是我的序列化器類:

class CommentSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Comment 
     depth = 2 

型號:

class Comment(models.Model): 
    user = models.ForeignKey(User, null=True, blank=True, 
     related_name='comments') 
    budget = models.ForeignKey(Budget, related_name='comments') 
    published = models.BooleanField(default=False) 
    body = models.TextField() 
    created = models.DateTimeField(auto_now_add=True) 

視圖代碼:

class Comments(generics.ListCreateAPIView): 

    model = Comment 
    serializer_class = CommentSerializer 

    def pre_save(self, obj): 
     obj.user = self.request.user 

,這是顯示在輸出誤差(JSON)是:

{"user": ["This field is required."], "budget": [{"non_field_errors": ["Invalid data"]}]} 

當這些原始數據被髮送出去。

{"budget": 2, "published": true, "body": "Another comment"} 
+0

隨機問題,如果你發送'{「budget_id」:2}'或'{「budget」:{「id」:2}}? – 2013-04-08 19:20:20

+0

RE @Nathan Villaescusa。那麼它期望按照需要顯示其他預算字段。 – panchicore 2013-08-25 21:24:45

回答

6

我認爲正確的方式來定義是指一個外鍵關係是通過像serializers.PrimaryKeyRelatedField串行場。我不相信模型序列化器會自動使用這個字段類,而沒有在序列化器類中明確地定義它。

http://www.django-rest-framework.org/api-guide/relations/#primarykeyrelatedfield

我會想象一個PrimaryKeyRelatedField串行將正確處理好喜歡你在你的例子中使用的JSON數據提交。

+6

對於那些從谷歌來到這裏的人,Tom Christie(DRF的創建者)在這裏寫了更多關於此的內容:https://groups.google.com/d/msg/django-rest-framework/vCl2I_EzJnE/qwRdIdxiUe4J – 2013-09-12 05:14:21

6

我知道這是一個有點晚,但我最終使用2個串行像這樣:

class CommentReadSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Comment 
     depth = 2 

class CommentWriteSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Comment 

然後像這樣使用:

class Comments(generics.ListCreateAPIView): 

    model = Comment 
    serializer_class = CommentReadSerializer 

    def create(self, request, *args, **kwargs): 
     serializer = CommentWriteSerializer(data=request.DATA, files=request.FILES) 
     if serializer.is_valid(): 
      self.pre_save(serializer.object) 
      self.object = serializer.save(force_insert=True) 
      self.post_save(self.object, created=True) 
      headers = self.get_success_headers(serializer.data) 
      serializer = CommentReadSerializer(serializer.object) 
      return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) 

     return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 
1

您可以通過重寫get_serializer_class()設置不同的串行功能如下:

def get_serializer_class(self): method = self.request.method if method == 'PUT' or method == 'POST': return YourWriteSerializer else: return YourReadSerializer

我想添加這個,因爲我在一段時間後從谷歌搜索過來。