DRF使用带有source参数的序列化程序更新资源

时间:2016-03-16 11:11:51

标签: python django django-rest-framework

我有以下代码。

class UserSerializer(serializers.ModelSerializer):
   fax = serializers.CharField(source='primary_address.fax')

class User(models.Model):
    primary_address = models.OneToOneField(ProfileAddress, verbose_name=_('Primary address'), null=True, related_name='+')

class ProfileAddress(models.Model):
   fax = models.CharField(max_length=255, verbose_name=_('Fax number'), null=True)
   mobile = models.CharField(max_length=255, verbose_name=_('Mobile phone number'), null=True)

当我尝试通过发送传真字段更新用户对象时,我将收到错误

Cannot assign "{u'fax': u'0555400123457'}": "User.primary_address" must be a "ProfileAddress" instance.

更新此类字段的正确方法是什么,这些字段定义与相关模型对应的源参数。可以在该相关模型上定义更多字段,它们都应该在json输出中表示为字段,而不是嵌套字段。

UPDATE 在我的序列化程序更新中的validated_data.items中,我看到以下内容:

 (u'primary_address', {u'city': {u'name': u'Berlin'}, u'fax': u'0555400123457', u'url': None, u'line1': u'Sch\xf6nhauser Allee', u'phone': u'0555400123456', u'postal_code': u'PostalCode object', u'email': u'abv@gmsail.comso'}),  (u'title', u'Herr')

显然是ModelSerializer的更新代码:

for attr, value in validated_data.items():
    setattr(instance, attr, value)

只是尝试将primary_address属性设置为字典值,它将失败。

1 个答案:

答案 0 :(得分:2)

您应该覆盖update功能以自行更新primary_address.fax

class UserSerializer(serializers.ModelSerializer):
    fax = serializers.CharField(source='primary_address.fax')

    def update(self, instance, validated_data):
        fax = validated_data.pop('fax', None)
        super(UserSerializer, self).update(instance, validated_data)
        if fax is not None:
            instance.primary_address.fax = fax
            instance.primary_address.save(update_fields=('fax',))
        return instance