Сериализация полей модели во вложенный объект / dict - PullRequest
0 голосов
/ 08 июня 2018

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

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()

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

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

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

из 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
0 голосов
/ 08 июня 2018

Вы можете просто определить 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}
...