将模型字段序列化为嵌套对象/字典

nko*_*ber 5 python django serialization django-rest-framework drf-yasg

想象一下以下模型:

class Person(models.Model):
    name = models.CharField()
    address_streetname = models.CharField()
    address_housenumber = models.CharField()
    address_zip = models.CharField()
Run Code Online (Sandbox Code Playgroud)

我有一个ModelSerializer暴露所有字段的 django rest 框架。但我希望能够将地址字段序列化为 dict。所以当序列化为 json 输出时:

{
    name: 'Some name',
    address: {
        streetname: 'This is a test',
        housenumber: '23',
        zip: '1337',
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试创建创建一个 AddressSerializer

class Address(object):
    ...

class AddressSerializer(serializers.Serializer):
    streetname = serializers.CharField()
    housenumber = serializers.CharField()
    zip = serializers.CharField()
    ...
Run Code Online (Sandbox Code Playgroud)

然后设置PersonSerializer.address使用AddressSerializer

class PersonSerializer(serializers.ModelSerializer):
    ...
    address = AddressSerializer()
Run Code Online (Sandbox Code Playgroud)

这导致我的架构是正确的。我使用drf-yasg. 它查看序列化程序以生成正确的模型定义。所以序列化器需要表示模式。

所以这就是我目前所处的位置。显然现在它失败了,因为模型中没有address属性Person。你会如何解决这个问题?

JPG*_*JPG 11

来自DRF-doc forsource 说,

该值source='*'具有特殊含义,用于指示应将整个对象传递到该字段。这对于创建嵌套表示或需要访问完整对象以确定输出表示的字段非常有用。


所以,试试这个,

class AddressSerializer(serializers.Serializer):
    streetname = serializers.CharField(source='address_streetname')
    housenumber = serializers.CharField(source='address_housenumber')
    zip = serializers.CharField(source='address_zip')


class PersonSerializer(serializers.ModelSerializer):
    # .... your fields
    address = AddressSerializer(source='*')

    class Meta:
        fields = ('address', 'other_fields')
        model = Person
Run Code Online (Sandbox Code Playgroud)