如何正确序列化与DRF的* -to-many关系

时间:2014-06-11 04:52:22

标签: python django rest serialization django-rest-framework

我一直在尝试使用DRF序列化/反序列化一些数据,但我不确定出了什么问题。


这是我的模特:

from django.db import models

class FooA(models.Model):
    propA = models.CharField(max_length=30)

class FooB(models.Model):
    propB = models.CharField(max_lenght=30)
    propC = models.ForeignKey(FooC, related_name='fooBs')

class FooC(models.Model):
    propC = models.CharField(max_lenght=30)
    fooAs = models.ManyToMany(FooA, null=True, blank=True)


这是我的序列化器:

from rest_framework import serializers
from myModule import models

class FooASerializer(serializers.ModelSerializer):
    class Meta:
        model = models.FooA
        fields = ('propA',)

class FooBSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.FooB
        fields = ('propB',)

class FooCSerializer(serializers.ModelSerializer):
    fooBs = FooBSerializer(many=True)
    fooAs = FooASerializer(many=True, required=False)

    class Meta:
        model = models.FooC
        fields = ('fooAs', 'fooBs',)


这是我的“观点”:

from rest_framework import generics
from .serializers import FooCSerializer
from .models import FooC

class FooCList(generics.ListCreateAPIView):
    model = FooC
    serializer_class = FooCSerializer


最后,这是我的路由:

from django.conf.urls import patterns, url, include
from .views import FooCList

urlpatterns = patterns('',
    url(r'^foocs/', FooCList.as_view())
)


所以,我试图通过管理界面创建一些数据,然后转到DRF api浏览器,复制一个FooC对象的JSON,稍微修改它并测试我是否成功将其反序列化为FooC对象。 / p>

以下是我所做的:

>>> from rest_framework.compat import BytesIO
>>> from rest_framework.parsers import JSONParser
>>> from myApp.serializers import FooCSerializer
>>>
>>> content = '<slightly modified JSON copied from the DRF api browser>'
>>> stream = BytesIO(content)
>>> data = JSONParser().parse(stream)
>>> serializer = FooCSerializer(data=data)
>>> serializer.is_valid()
True
>>> serializer.save()
ValueError: Cannot add "<FooA: fooA>": instance is on database "default", value is on database "None"


请注意,它确实在我的数据库中创建了一个新的FooC实例,但它并没有创建它的“嵌套”类(也就是.FooC与它有关系的类)。


所以这里有几个问题:

1)这是预期的吗?我希望它能在“级联”中创建所有内容。

2)如果这种情况发生在设计中,我在构建客户端时应该怎么做?我的意思是,我希望打开一个表单来创建FooC的实例和每个相关的同一形式的实例。

谢谢你们,伙计们!

1 个答案:

答案 0 :(得分:0)

简答:

1)是的。

2)可能有解决方法。

为了让您理解为什么我对第一个问题说“是”,我建议您阅读DRF创始人Tom Christie撰写的https://groups.google.com/forum/#!msg/django-rest-framework/vCl2I_EzJnE/qwRdIdxiUe4J解释。

现在有解决方法,您可以:

1)使用pre_save方法在for循环中创建嵌套对象,然后将它们的PK添加到FooC当前实例

2)为嵌套类创建一个视图,然后使用请求中的相应数据从该视图调用该方法。

希望这会有所帮助:)