Serializing ManyToMany Relationships with an Intermediate Model in the Django Rest Framework

I'm having trouble serializing many, many relationships with pass-through argument in DRF3

I mainly have recipes and ingredients combined through an intermediate model that determines the amount and units used for a particular ingredient.

These are my models:

      
from django.db import models
from dry_rest_permissions.generics import authenticated_users, allow_staff_or_superuser
from core.models import Tag, NutritionalValue
from usersettings.models import Profile

class IngredientTag(models.Model):
    label = models.CharField(max_length=255)

    def __str__(self):
        return self.label


class Ingredient(models.Model):
    recipe = models.ForeignKey('Recipe', on_delete=models.CASCADE)
    ingredient_tag = models.ForeignKey(IngredientTag, on_delete=models.CASCADE)
    amount = models.FloatField()
    unit = models.CharField(max_length=255)


class RecipeNutrition(models.Model):
    nutritional_value = models.ForeignKey(NutritionalValue, on_delete=models.CASCADE)
    recipe = models.ForeignKey('Recipe', on_delete=models.CASCADE)
    amount = models.FloatField()


class Recipe(models.Model):
    name = models.CharField(max_length=255)
    ingredients = models.ManyToManyField(IngredientTag, through=Ingredient)
    tags = models.ManyToManyField(Tag, blank=True)
    nutritions = models.ManyToManyField(NutritionalValue, through=RecipeNutrition)
    owner = models.ForeignKey(Profile, on_delete=models.SET_NULL, blank=True, null=True)

    def __str__(self):
        return self.name

And these are my serializers these days:

from recipes.models import Recipe, IngredientTag, Ingredient
from rest_framework import serializers

class IngredientTagSerializer(serializers.ModelSerializer):
    class Meta:
        model = IngredientTag
        fields = ('id', 'label')

class IngredientSerializer(serializers.ModelSerializer):
    class Meta:
        model = Ingredient
        fields = ('amount', 'unit')

class RecipeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Recipe
        fields = ('id', 'url', 'name', 'ingredients', 'tags', 'nutritions', 'owner')
        read_only_fields = ('owner',)
        depth = 1

I have searched for SO and on the Internet quite a lot, but I cannot figure it out. It would be great if someone could point me in the right direction.

I can get a list of ingredients that will be returned like this:

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "id": 1,
            "url": "http://localhost:8000/recipes/1/",
            "name": "Hallo recept",
            "ingredients": [
                {
                    "id": 1,
                    "label": "Koek"
                }
            ],
            "tags": [],
            "nutritions": [],
            "owner": null
        }
    ]
}

But I want the amount and unit also to be returned!

+4
source share
3

, , :

from recipes.models import Recipe, IngredientTag, Ingredient
from rest_framework import serializers

class IngredientTagSerializer(serializers.ModelSerializer):
    class Meta:
        model = IngredientTag
        fields = ('id', 'label')

class IngredientSerializer(serializers.ModelSerializer):
    ingredient_tag = IngredientTagSerializer()

    class Meta:
        model = Ingredient
        fields = ('amount', 'unit', 'ingredient_tag')

class RecipeSerializer(serializers.ModelSerializer):
    ingredients = IngredientSerializer(source='ingredient_set', many=True)

    class Meta:
        model = Recipe
        fields = ('url', 'name', 'ingredients', 'tags', 'nutritions', 'owner')
        read_only_fields = ('owner',)
        depth = 1

componentent_tag componentent_set IngredientSerializer, , :

{
    "count": 1,
    "next": null,
    "previous": null,
    "results": [
        {
            "url": "http://localhost:8000/recipes/1/",
            "name": "Hallo recept",
            "ingredients": [
                {
                    "amount": 200.0,
                    "unit": "g",
                    "ingredient_tag": {
                        "id": 1,
                        "label": "Koek"
                    }
                },
                {
                    "amount": 500.0,
                    "unit": "kg",
                    "ingredient_tag": {
                        "id": 3,
                        "label": "Sugar"
                    }
                }
            ],
            "tags": [],
            "nutritions": [],
            "owner": null
        }
    ]
}

, , , -, , DRF , , - - , .

+3

ManyToManyField.

:

class RecipeSerializer(serializers.ModelSerializer):

    ingredients = serializers.SerializerMethodField()

    def get_ingredients(self, obj):
        serializer = IngredientSerializer(obj.ingredients)
        return serializer.data    

    class Meta:
        model = Recipe
        fields = ('id', 'url', 'name', 'ingredients', 'tags', 'nutritions', 'owner')
        read_only_fields = ('owner',)
        depth = 1

(, , ), , . , json.

. ManyToManyField "", "", DRF "get _".

, :

Django Rest Framework - SerializerMethodField

+2

Override the to_representation RecipeSerializer method and pass an instance of many for many served to their serializer, many of which are True. or

tags = serializers.HyperlinkedRelatedField (many = True, read_only = True,)

0
source

All Articles