Сериализация полей модели во вложенный объект /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}