2016-01-13 88 views
2

根据Django REST Framework版本3 documentation,为了创建可写入嵌套序列化器,您需要编写自己的create()update()方法。我有阅读和写作的工作,但更新不起作用。例如,如果我将以下数据发送到我的序列化器3次,我最终创建了3个新的Widget。我预计传递一个预先存在的id会触发更新并呼叫update(),但是会调用create()。似乎id被忽略,这是有道理的,因为它是自动生成的,所以我如何实现这一点?Django REST Framework嵌套序列化器不会更新

我有一种感觉,我错过了一些明显的东西,也许在我看来有些额外的处理?

views.py(目前确实粗糙,请原谅)

from rest_framework.decorators import api_view 
from rest_framework.response import Response 

from widget.models import Widget 
from widget.serializers import WidgetSerializer 

@api_view() 
def create(request): 

    data = { 
     "id": 4, 
     "widget_alpha": { 
      "bits": [ 
       { 
        "id": 3, 
        "name": "bit 1", 
        "widget": 4 
       } 
      ], 
      "bobs": [ 
       { 
        "id": 3, 
        "name": "bob 1", 
        "widget": 4 
       } 
      ], 
      "name": "my wid", 
      "widget": 4 
     }, 
     "language": "en", 
     "code": "123" 
    } 

    serializer = WidgetSerializer(data=data) 
    if serializer.is_valid(): 
     serializer.save() 
    else: 
     print serializer.errors 

    return Response({"message": "yay"}) 

Widget是一个父模型,WidgetAlpha是一个孩子,是由几个位和鲍勃的。下面的代码相关的models.pyserializers.py

models.py

from django.db import models 

class Widget(models.Model): 
    LANGUAGE = (
     ('fr', 'French'), 
     ('en', 'English'), 
    ) 

    language = models.CharField(max_length=2, choices=LANGUAGE) 
    code = models.CharField(max_length=6) 

class WidgetAlpha(models.Model): 
    widget = models.OneToOneField(Widget, primary_key=True, related_name='widget_alpha') 
    name = models.CharField(max_length=6) 

class Bit(models.Model): 

    widget = models.ForeignKey(WidgetAlpha, related_name='bits') 
    name = models.CharField(max_length=6) 

class Bob(models.Model): 

    widget = models.ForeignKey(WidgetAlpha, related_name='bobs') 
    name = models.CharField(max_length=6) 

serializers.py

from rest_framework import serializers 

from widget.models import Widget, WidgetAlpha, Bit, Bob 

class BitsSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Bit 

class BobsSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Bob 

class WidgetAlphaSerializer(serializers.ModelSerializer): 

    bits = BitsSerializer(many=True) 
    bobs = BobsSerializer(many=True) 

    class Meta: 
     model = WidgetAlpha 

class WidgetSerializer(serializers.ModelSerializer): 
    widget_alpha = WidgetAlphaSerializer() 

    class Meta: 
     model = Widget 

    def create(self, validated_data): 
     widget_alpha_data = validated_data.pop('widget_alpha')  
     bits_data = widget_alpha_data.pop('bits') 
     bobs_data = widget_alpha_data.pop('bobs') 

     widget = Widget.objects.create(**validated_data) 
     alpha_widget = WidgetAlpha.objects.create(widget=widget, **widget_alpha_data) 

     for bit_data in bits_data: 
      Bit.objects.create(widget=alpha_widget, **bit_data) 

     for bob_data in bobs_data: 
      Bob.objects.create(widget=alpha_widget, **bob_data) 

     return widget 

    def update(self, instance, validated_data): 
     # never get here :(
     return instance 
+0

你可以添加你的看法呢? – DevilPinky

+0

views.py已被添加 – redgoose

+2

你不要在任何地方调用'update'。如果你想调用一个更新,你需要创建类似如下的串行器对象:'serializer = WidgetSerializer(object,data = data)' – DevilPinky

回答

2

为了的WidgetSerializer.update()方法被调用,你需要以不同的实例序列化。

尝试使用这样的事情:

widget = Widget.get(pk=something) 

serializer = WidgetSerializer(widget, data=data, partial=True) #you need partial if you want to update only some fields 
if serializer.is_valid(): 
    serializer.save() 
else: 
    print serializer.errors 
相关问题