Как произвольно вложить некоторые данные в сериализатор фреймворка django rest
Существующий клиент уже отправляет данные в структуре типа...
{
"hive_metadata": {"name": "hive name"},
"bees": [{"name": "bee 1", "name": "bee 2", ...}]
}
Для таких моделей, как:
class Hive(models.Model):
name = models.CharField(max_length=32, help_text="name")
class Bee(models.Model):
name = models.CharField(max_length=32, help_text="name")
hive = models.ForeignKey(
Hive, help_text="The Hive associated with this Bee", on_delete=models.CASCADE
)
Код, который делает это возможным, вручную итерирует входящие данные. Я хотел бы переписать его, используя сериализатор фреймворка django rest; однако тот факт, что hive_metadata
сам по себе является вложенным, пока что ставит меня в тупик.
Если я напишу
class BeesSerializer(ModelSerializer):
class Meta:
model = models.Bee
fields = ("name",)
class PopulatedHiveSerializer(ModelSerializer):
bees = BeesSerializer(many=True, source="bee_set")
class Meta:
model = models.Hive
fields = ("name","bees",)
будет производить
{
"name": "hive name",
"bees": [{"name": "bee 1", "name": "bee 2", ...}]
}
достаточно легко. Я надеялся, что смогу решить эту проблему с помощью ссылки на субсериализатор, что-то вроде
class HiveMetaDataSerializer(ModelSerializer):
class Meta:
model = models.Hive
fields = ("name",)
class PopulatedHiveSerializer(ModelSerializer):
bees = BeesSerializer(many=True, source="bee_set")
hive_metadata = HiveMetaDataSerializer(source=???)
class Meta:
model = models.Hive
fields = ("hive_metadata","bees",)
но я никак не могу понять, что поместить в "источник", чтобы один и тот же объект проходил через внешний сериализатор во внутренний.
Итак, есть ли способ сделать это, используя сериализатор фреймворка django rest?
Вы можете использовать строковый литерал с астериском ('*'
), как указано в документации [drf-doc]:
value source='*'
имеет особое значение и используется для указания на то. что весь объект должен быть передан в поле. Это может полезно для создания вложенных представлений или для полей, которым требуется доступ к полному объекту для определения выходного представление.
поэтому мы можем использовать:
class PopulatedHiveSerializer(ModelSerializer):
bees = BeesSerializer(many=True, source='bee_set')
hive_metadata = HiveMetaDataSerializer(source='*')
class Meta:
model = models.Hive
fields = (
'hive_metadata',
'bees',
)