Django-rest-framework,Serializers中的嵌套对象

db0*_*db0 7 serialization nested django-rest-framework

我想在序列化器中有一个嵌套对象,而不仅仅是外键(或url).正如本文档所述,我只需在父序列化程序中指定嵌套对象的序列化程序类:

# Models

class NestedSample(models.Model):
    something = models.CharField(max_length=255)

class Sample(models.Model):
    thing = models.BooleanField()
    nested = models.ForeignKey(NestedSample)

# Serializers

class NestedSampleSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = api_models.NestedSample

class SampleSerializer(serializers.HyperlinkedModelSerializer):
    nested = NestedSampleSerializer() # HERE!

    class Meta:
        model = api_models.Sample

# Views

class NestedSampleViewSet(viewsets.ModelViewSet):
    queryset = api_models.NestedSample.objects.all()
    serializer_class = api_serializers.NestedSampleSerializer

class SampleViewSet(viewsets.ModelViewSet):
    queryset = api_models.Sample.objects.all()
    serializer_class = api_serializers.SampleSerializer
Run Code Online (Sandbox Code Playgroud)

当我获得对象时,这非常有效,但是不可能再创建(= POST)Sample对象,我得到错误:

{u'non_field_errors': [u'Invalid data']}
Run Code Online (Sandbox Code Playgroud)

我试图覆盖create视图集中的方法来使用pk获取对象:

class SampleViewSet(viewsets.ModelViewSet):
    queryset = api_models.Sample.objects.all()
    serializer_class = api_serializers.SampleSerializer

    def create(self, request):
        request.DATA['nested'] = get_object_or_404(api_models.NestedSample, pk=request.DATA['nested'])
        return super(SampleViewSet, self).create(request)
Run Code Online (Sandbox Code Playgroud)

但它不起作用.

任何的想法?

我也发现了这个问题,我可以解决这个问题当然解决了问题,但是不要让我公开完整的嵌套对象,所以回到开头.

谢谢,

zap*_*.10 2

我可以想到解决这个问题的两种方法。我更喜欢第一个。

第一个解决方案:

使用 django 模型表单来创建对象。重写创建和更新方法。创建方法示例:

def create(self, request):
    form = SampleForm(data=request.POST)
    if form.is_valid():
        instance = form.save(commit=False)
        instance.save()
        return Response(dict(id=instance.pk), status=status.HTTP_201_CREATED)
    return Response(form.errors, status=status.HTTP_400_BAD_REQUEST)
Run Code Online (Sandbox Code Playgroud)

这样您就可以使用您喜欢的任何类型的验证来创建示例对象。

第二种解决方案:

重写 get_serializer_class 方法并根据请求方法返回序列化器类。定义两个序列化器,一个用于 post 和 put,另一个用于 list 和retrieve。