Сериализация полей модели во вложенный объект /dict

Представьте себе следующую модель:

class Person(models.Model):
    name = models.CharField()
    address_streetname = models.CharField()
    address_housenumber = models.CharField()
    address_zip = models.CharField()

У меня есть рамки для отдыха Django ModelSerializer который выставляет все поля. Но я хотел бы иметь возможность сериализации адресных полей в диктовку. Таким образом, при сериализации в JSON вывод будет:

{
    name: 'Some name',
    address: {
        streetname: 'This is a test',
        housenumber: '23',
        zip: '1337',
    }
}

Я пытался создать создание AddressSerializer

class Address(object):
    ...

class AddressSerializer(serializers.Serializer):
    streetname = serializers.CharField()
    housenumber = serializers.CharField()
    zip = serializers.CharField()
    ...

а затем установите PersonSerializer.address использовать AddressSerializer

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

Это приводит к моей правильной схеме. Я генерирую документы о чванстве с помощью drf-yasg, Он смотрит на сериализаторы для генерации правильных определений модели. Таким образом, сериализаторы должны представлять схему.

Вот где я сейчас нахожусь. Очевидно, что теперь это не удается, потому что нет address недвижимость в Person модель. Как вы решите это?

2 ответа

Решение

Из DRF-документа для source говорит,

Значение 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

Вы можете просто определить property:

class Person(models.Model):
    name = models.CharField()
    address_streetname = models.CharField()
    address_housenumber = models.CharField()
    address_zip = models.CharField()

    @property
    def address(self):
    return {'streetname': self.address_streetname,
            'housenumber': self.address_housenumber,
            'zip': self.address_zip}
Другие вопросы по тегам