uke*_*joe 5 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, blank=True)
Run Code Online (Sandbox Code Playgroud)
我创建了一个 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',)
Run Code Online (Sandbox Code Playgroud)
然后我创建了一个视图来为 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)
Run Code Online (Sandbox Code Playgroud)
当我的 POST 数据有一个带有唯一名称属性的 facebook 对象时,这很好用。但是,如果 facebook 信息是可选的呢?我在 PersonSerializer 的 facebook 字段中设置了“required=False”来解决这个问题,但是当我的 POST 数据不包含 facebook 对象时,我收到了 400 错误。该错误表明 facebook 的“名称”字段是必需的。
如果我在 FacebookAccount 模型的 name 字段上设置“blank=True”,并且不在我的 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',)
Run Code Online (Sandbox Code Playgroud)
allow_null=True只需在父序列化器中声明嵌套序列化器时传递即可,如下所示:
class FacebookSerializer(serializers.ModelSerializer):
class Meta:
model = FacebookAccount
fields = ('name', 'page_id',)
class PersonSerializer(serializers.ModelSerializer):
facebook = FacebookSerializer(allow_null=True, required=False)
class Meta:
model = Person
fields = ('id', 'name', 'facebook',)
Run Code Online (Sandbox Code Playgroud)
小智 1
好吧,这就是 django-restframework 在将反向关系指定为字段时的限制,因为它从指定的字段创建一个列表,required=false 仅指示序列化器保存该相关字段的默认空值,以便您解决它可以重写序列化器的 save_object 方法并删除 facebook 字段(如果为空)。