Django Rest Framework可选的嵌套序列化器字段在ModelSerializer中

时间:2014-09-16 05:45:21

标签: django django-rest-framework

我有两个模特:FacebookAccount和Person。这样的OneToOne关系是这样的:

class FacebookAccount(models.Model):
    person = models.OneToOneField(Person, related_name='facebook')
    name = models.CharField(max_length=50, unique=True)
    page_id = models.CharField(max_length=100, blank=True)

我创建了一个PersonSerializer,其facebook字段设置为我创建的FacebookSerializer:

class FacebookSerializer(serializers.ModelSerializer):
    class Meta:
        model = FacebookAccount
        fields = ('name', 'page_id',)

class PersonSerializer(serializers.ModelSerializer):
    facebook = FacebookSerializer(required=False)

    class Meta:
        model = Person
        fields = ('id', 'name', 'facebook',)

然后我创建了一个视图,为POST请求创建一个新的Person以及一个新的FacebookAccount实例:

class PersonCreate(APIView):

    def post(self, request):
        # Checking for something here, doesn't affect anything
        if 'token' in request.DATA:
            serializer = PersonSerializer(data=request.DATA)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

当我的POST数据中有一个具有唯一名称属性的facebook对象时,这很好用。但是,如果facebook信息是可选的呢?我设置" required = False"在PersonSerializer的facebook字段中考虑到这一点,但是当我的POST数据不包含facebook对象时,我收到400错误。错误说" name" Facebook的字段是必需的。

如果我设置"空白=真"在FacebookAccount模型的名称字段中,并且在我的POST数据中没有提供和Facebook信息,创建了一个空白的FacebookAccount记录,这是预期但不需要的。

有谁知道如何解决这个问题?感谢。

编辑:

我尝试覆盖PersonSerializer上的save_object方法,但看起来该方法没有被调用。我试着通过调用的方法返回工作,看起来get_field是最后一个:

class PersonSerializer(serializers.ModelSerializer):
    facebook = FacebookSerializer(required=False)

    def get_default_fields(self):
        field = super(PersonSerializer, self).get_default_fields()
        print field
        return field

    def get_pk_field(self, model_field):
        print 'MF'
        mf = super(PersonSerializer, self).get_pk_field(model_field)
        print mf
        return mf

    def get_field(self, model_field):
        print 'FIELD'
        mf = super(PersonSerializer, self).get_field(model_field)
        print mf
        return mf

    # not called
    def get_validation_exclusions(self, instance=None):
        print '**Exclusions'
        exclusions = super(PersonSerializer, self).get_validation_exclusions(instance=None)
        print exclusions
        return exclusions

    # not called
    def save_object(self, obj, **kwargs):
        if isinstance(obj, FacebookAccount):
            print 'HELLO'
        else:
            print '*NONONO'
        return super(PersonSerializer, self).save_object(obj, **kwargs)

    class Meta:
        model = Person
        fields = ('id', 'name', 'stripped_name', 'source', 'facebook',)

3 个答案:

答案 0 :(得分:1)

那么,当将反向关系指定为字段时,这是django-restframework的限制,因为它从指定的字段创建列表,required = false仅指示序列化程序将该相关字段的默认空值保存到解决它你可以覆盖序列化器的save_object方法,如果它为null,则删除facebook字段。

答案 1 :(得分:0)

很抱歉迟到的回复,我有一些类似的模型,它正在工作,通过重写save_object方法,is_valid()必须返回false(你检查过它),无论如何使用序列化程序保存对象是非常基本的用例因此有限,最好的方法是在视图中明确地保存这些对象。

答案 2 :(得分:0)

在父级序列化器中声明嵌套的序列化器时,只需传递allow_null=True,如下所示:

class FacebookSerializer(serializers.ModelSerializer):
    class Meta:
        model = FacebookAccount
        fields = ('name', 'page_id',)

class PersonSerializer(serializers.ModelSerializer):
    facebook = FacebookSerializer(allow_null=True)

    class Meta:
        model = Person
        fields = ('id', 'name', 'facebook',)