在Django Rest Framework嵌套Serializer中重用现有对象

Ale*_*erg 7 django django-models django-rest-framework

在drf中使用嵌套的Serializers时,如何重新使用引用的对象:

假设我有以下两个Model:

class Address(models.Model):
    address_line = models.CharField(max_length=45)

class Person(models.Model):
    name = models.CharField(max_length=45)
    address = models.ForeignKey(Address)
Run Code Online (Sandbox Code Playgroud)

Serializers:

class AddressSerializer(serializers.ModelSerializer):
    class Meta:
        model = Address

class PersonSerializer(serializers.ModelSerializer):
    address = AddressSerializer()

    class Meta:
        model = Person
Run Code Online (Sandbox Code Playgroud)

现在,Serializers处理创建AddressPerson共同创建.例如,当我发布以下内容时:

{
    'name': 'Alex',
    'address': {
        'address_line': "1 Here"
    }
}
Run Code Online (Sandbox Code Playgroud)

一个Person创建和Address与创建Person指向新创建的Address.

如果已经有一个给定的东西,那么不创建新的Address但是重用现有的最好的方法Address是什么?即如果我想创造这个领域?(此对象重用有时称为"实习")Addressaddress_lineaddress_lineunique

如果有两个地址字段address_line1并且address_line2我想重新使用该Address对象,如果已经存在这Address两个字段(即unique_together=(address_line1, address_line2))?

Ank*_*pli 2

最近我遇到了类似的问题,使用以下方法解决了它(代码未经测试,仅供参考):

class PersonSerializer(serializers.ModelSerializer):
    address = AddressSerializer()

    class Meta:
        model = Person

    def create(self, validated_data):
        # pop the validated user data
        # assuming its a required field,
        # it will always be there in validated_data
        address = validated_data.pop('address')

        try:
            address = Address.objects.get(address_line=address.get('address_line'))
        except ObjectDoesNotExist:
            address_serializer = AddressSerializer(data=address)
            address_serializer.is_valid(raise_exception=True)
            address = address_serializer.save()
        else:
            # save the user and update the validated_data for setting up profile
            validated_data['address'] = address

        return super(PersonSerializer, self).create(validated_data)
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助 :)