Вложенность полей в сериализаторе

Есть 3 модели (рецепт, ингредиенты рецепта, ингредиенты)

class Ingredient(models.Model):
    name = models.CharField(
        verbose_name='Название ингредиента',
        help_text='Название фрукта, овоща, соуса или иной продукт',
        max_length=200,
    )
    measurement_unit = models.CharField(
        verbose_name='Единица измерения',
        help_text='Применяйте наиболее подходящую единицу измерения',
        max_length=200,
    )

    class Meta:
        ordering = ['id']
        verbose_name = 'Ингредиент'
        verbose_name_plural = 'Ингредиенты'
        constraints = [
            models.UniqueConstraint(
                fields=['name', 'measurement_unit'],
                name='Уникальная запись ингредиент - единица измерения',
            )
        ]

    def __str__(self):
        return self.name


class Recipe(models.Model):
    tag = models.ManyToManyField(
        Tag,
        related_name='recipes',
    )
    author = models.ForeignKey(
        User,
        verbose_name='Автор',
        related_name='recipes',
        on_delete=models.CASCADE,
    )
    name = models.CharField(
        verbose_name='Название рецепта',
        help_text='Например "Оливье"',
        max_length=200,
    )
    image = models.ImageField(
        verbose_name='Изображение',
        help_text='Загрузите изображение для вашего рецепта',
        upload_to='images/',
    )
    text = models.TextField(
        verbose_name='Описание',
        help_text='Описание блюда, инструкция по приготовлению, советы и т.д.',
    )
    cooking_time = models.IntegerField(
        verbose_name='Время приготовления',
        help_text='Время приготовления (в минутах), целое число',
        validators=[
            MinValueValidator(
                1,
                'Время приготовления не может быть меньше 1 минуты',
            )
        ]
    )
    pub_date = models.DateTimeField(
        verbose_name='Дата публикации',
        auto_now_add=True,
        db_index=True,
    )

    class Meta:
        ordering = ['pub_date']
        verbose_name = 'Рецепт'
        verbose_name_plural = 'Рецепты'

    def __str__(self):
        return f'{self.name}\n{self.text}'


class RecipeIngredient(models.Model):
    ingredient = models.ForeignKey(
        Ingredient,
        verbose_name='Ингредиент',
        help_text='Выберите ингредиент',
        on_delete=models.CASCADE,
    )
    recipe = models.ForeignKey(
        Recipe,
        related_name='ingredients',
        on_delete=models.CASCADE,
    )
    amount = models.IntegerField(
        verbose_name='Количество',
        help_text='Требуемое количество для рецепта (целое число)',
    )

    class Meta:
        verbose_name = 'Ингредиент рецепта'
        verbose_name_plural = 'Ингредиенты рецепта'

    def __str__(self):
        return self.ingredient.name

Рецепт содержит ингредиенты с их количеством, т.е. модель RecipeIngredient это связка двух таблиц с дополнительным молем amount. Сериализаторы:

class IngredientSerializer(serializers.ModelSerializer):

    class Meta:
        model = Ingredient
        fields = [
            'id',
            'name',
            'measurement_unit',
        ]


class RecipeIngredientSerializer(serializers.ModelSerializer):
    ingredient = IngredientSerializer()

    class Meta:
        model = RecipeIngredient
        fields = [
            'ingredients',
            'amount',
        ]


class RecipeSerializer(serializers.ModelSerializer):

    class Meta:
        model = Recipe
        fields = [
            'id',
            'tags',
            'author',
            'ingredients',
            'name',
            'image',
            'text',
            'cooking_time',
        ]

Я пытаюсь получить от api список ингредиентов в таком виде

"ingredients": [
{
"id": 0,
"name": "Картофель отварной",
"measurement_unit": "г",
"amount": 1
}
]

Но естественно поле amount будет на уровне ingredients а не внутри него. Что и как переделать в сериализаторах, что бы получить заветный результат?

Вернуться на верх