2015-09-15 93 views
0

我有一個Django模型W /使用的用於M2M關係通過模型:Django的休息框架PUT多對多通過模型

models.py

class ModelA(models.Model): 
    name = models.CharField(max_length=64) 

class ModelB(models.Model): 
    name = models.CharField(max_length=64) 
    other_models = models.ManyToManyField("ModelA", through="ModelC") 

class ModelC(models.Model): 
    model_a = models.ForeignKey("ModelA", related_name="link_to_model_a") 
    model_b = models.ForeignKey("ModelB", related_name="link_to_model_b") 
    some_other_info = models.TextField() 
    class Meta: 
     unique_together = ("model_a", "model_b",) 

我想這個序列化使用django-其餘的框架:

serializers.py

class ModelCSerializer(ModelSerializer): 
    class Meta: 
     model = ModelC 
     fields = ('id', 'model_a', 'model_b', 'some_other_info',) 

class QModelBSerializer(ModelSerializer): 
    class Meta: 
     model = ModelB 
     fields = ('id', 'other_models',) 
    other_models = ModelCSerializer(many=True, required=False, source="link_to_model_b") 

現在,對於現有車型的GET顯示p roperly:

{ 
    "id": 2, 
    "name": "i am an instance of model_b", 
    "other_models": [ 
    {"id": 1, "model_a": 1,"model_b": 2, "some_other_info":"here is some other info"} 
    ], 
} 

但是,如果我嘗試PUT一些數據失敗w/unique_together錯誤。我認爲把它作爲PUT發送會導致更新(不應該引發unique_together錯誤)而不是創建?下面是把代碼:

views.py

class ModelBDetail(APIView): 
    def put(self, request, pk, format=None): 
     model = ModelB.objects.get(id=pk) 
     serializer = ModelBSerializer(model, data=request.data, context={"request": request}) 
     if serializer.is_valid(): # THIS IS RETURNING FALSE 
      serializer.save() 
      return Response(serializer.data) 
     return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 

有什麼想法?

+0

您是否在發佈它時放棄了GET結果? – Ivan

+0

@伊萬 - 是的,沒有變化。 – trubliphone

回答

0

儘管@Ivan對編寫我自己創建的更新fn是正確的,但我看到的具體問題是嵌套序列化沒有與它關聯的實例屬性。

新的代碼如下所示:

serializers.py

class ModelBSerializer(ModelSerializer): 

    .... 

    def update(self, model_instance, validated_data): 
     model_c_serializer = self.fields["other_models"] 

     model_c_data = validated_data.pop(model_c_serializer.source, []) 

     for key, value in validated_data.iteritems(): 
      setattr(model_instance, key, value) 
     model_instance.save() 

     model_c_serializer.update(model_instance.link_to_model_b.all(), 
model_c_data) 

     return model_instance 

class ModelCSerializer(ModelSerializer): 

    ... 

    def to_internal_value(self, data): 

     # this is as good a place as any to set the instance 
     try: 
      model_class = self.Meta.model 
      self.instance = model_class.objects.get(pk=data.get("id")) 
     except ObjectDoesNotExist: 
      pass 

     return super(ModelCSerializer, self).to_internal_value(data) 

基本上,我叫update的嵌套串行明確,我也迫使每個嵌套串行檢查傳遞給數據他們爲一個例子。

相關問題