Django Rest Framework ModelSerializer中的可选嵌套序列化器字段
我有两个模型:FacebookAccount和Person。有这样一种一刀切的关系:Django Rest Framework ModelSerializer中的可选嵌套序列化器字段,django,django-rest-framework,Django,Django Rest Framework,我有两个模型:FacebookAccount和Person。有这样一种一刀切的关系: 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,
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)
当我的帖子数据中有一个facebook对象,其中有一个唯一的name属性时,这种方法很好用。但是,如果facebook信息是可选的呢?我在PersonSerializer的facebook字段中设置了“required=False”来解释这一点,但是当我的帖子数据不包含facebook对象时,我得到了400个错误。错误表明facebook的“名称”字段是必需的
如果我在FacebookAccount模型的name字段中设置了“blank=True”,并且没有在我的帖子数据中提供和facebook信息,则会创建一个空白的FacebookAccount记录,这是预期的,但不是期望的
有人知道如何解决这个问题吗?谢谢
编辑:
我尝试在PersonSerializer上重写save_对象方法,但该方法似乎没有被调用。我尝试通过调用的方法返回,看起来get_字段是最后一个:
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',)
这就是django restframework在将反向关系指定为字段时的限制,因为它从指定的字段创建列表,required=false仅指示序列化程序保存该相关字段的默认空值,若要解决此问题,您可以覆盖序列化程序的save_object方法,并在其为null时删除facebook字段。很抱歉,我有一些类似的模型,它正在工作,通过覆盖save_object方法,is_valid()必须返回false(您检查过它了吗),无论如何,使用序列化程序保存对象只适用于非常基本的用例,因此受到限制,最好的方法是在视图中显式保存这些对象。在父序列化程序中声明嵌套序列化程序时,只需传递
allow\u null=True
,如下所示:
类FacebookSerializer(serializers.ModelSerializer):
类元:
模型=FacebookAccount
字段=('name','page_id',)
类PersonSerializer(serializers.ModelSerializer):
facebook=FacebookSerializer(allow_null=True,required=False)
类元:
模特=人
字段=('id','name','facebook',)
谢谢您的回复。我该怎么做呢?我看到文档中说你可以这样做,但不要给出一个例子。不要忘记所解释的required=False