Как произвольно вложить некоторые данные в сериализатор фреймворка 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',
        )
Вернуться на верх