【问题标题】:include extra field in nested serializer with throuth model Django通过模型 Django 在嵌套序列化程序中包含额外字段
【发布时间】:2019-05-23 21:00:58
【问题描述】:

我正在写一个膳食跟踪器,所以有两个模型,Recipe 和 Ingredient,它们通过模型 RecipeIngredient 与额外字段 quantity 连接。

这是我的models.py:

class Recipe(models.Model):
    name = models.CharField(max_length=100)
    recipe = models.CharField(max_length=200)
    ingredients = models.ManyToManyField(Ingredient, through="RecipeIngredient", related_name='recipes')

class RecipeIngredient(models.Model):
    recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE, unique=False)
    ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE)
    quantity = models.IntegerField(blank=False)

class Ingredient(models.Model):
    id = models.AutoField(primary_key=True, db_column='ingredient_id')
    name = models.CharField(max_length=100)
    calories = models.IntegerField(blank=True)

views.py:

class RecipeViewSet(viewsets.ModelViewSet):
    queryset = Recipe.objects.all()
    serializer_class = RecipeSerializer
    permission_classes = (AllowAny,)

    def get_queryset(self):
        return Recipe.objects.annotate(
            total_ingredients=Count('ingredients'),
            total_calories=Sum('ingredients__calories'),
            total_quantity=Sum('recipeingredient__quantity')
        )
class IngredientViewSet(viewsets.ModelViewSet):
    queryset = Ingredient.objects.all()
    serializer_class = IngredientSerializer
    permission_classes = (AllowAny,)

serialziers.py:

class RecipeSerializer(serializers.ModelSerializer):
    ingredient_list = IngredientSerializer(source='ingredients', many=True, required=False)
    total_ingredients = serializers.IntegerField(required=False)
    total_calories = serializers.IntegerField(required=False)
    total_quantity = serializers.IntegerField(required=False)
    class Meta:
        model = Recipe
        fields = ('id', 'name', 'ingredient_list', 'recipe', 'total_ingredients', 'total_calories', 'total_quantity')
        depth = 1

class IngredientSerializer(serializers.ModelSerializer):

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

到目前为止,我的回复是这样的:

  {
      "id": 1,
      "name": "testrecipe",
      "ingredient_list": [
            {
                "id": 1,
                "name": "ing0",
                "calories": 2
            },
            {
                "id": 2,
                "name": "ing1",
                "calories": 4
            },
            {
                "id": 3,
                "name": "ing2",
                "calories": 4
            }
        ],
        "recipe": "recipe discription here",
        "total_ingredients": 3,
        "total_calories": 10,
        "total_quantity": 30
   },

我想为列表中的每种成分添加quantity,以便响应如下所示:

  {
      "id": 1,
      "name": "testrecipe",
      "ingredient_list": [
            {
                "id": 1,
                "name": "ing0",
                "calories": 2,
                "quantity":10
            },
            {
                "id": 2,
                "name": "ing1",
                "calories": 4,
                "quantity":15
            },
            {
                "id": 3,
                "name": "ing2",
                "calories": 4,
                "quantity":5
            }
        ],
        "recipe": "recipe discription here",
        "total_ingredients": 3,
        "total_calories": 10,
        "total_quantity": 30
   },

我可以通过<ingredient instance>.recipeingredient_set.all()[0].quantity 检索成分的数量,考虑到该成分仅在一个配方中,但我如何将此字段包含在序列化程序中,以及在哪个?

【问题讨论】:

    标签: python django many-to-many serialization


    【解决方案1】:

    在你的IngredientSerializer中使用SerializerMethodField,如下所示,

    class IngredientSerializer(serializers.ModelSerializer):
        quantity = serializers.SerializerMethodField()
    
        def get_quantity(self, ingredient_instance):
            recipe = ingredient_instance.recipeingredient_set.all().first()
            if recipe:
                return recipe.quantity
            else:
                return None
    
        class Meta:
            model = Ingredient
            fields = ['id', 'name', 'calories', 'quantity']

    【讨论】:

      【解决方案2】:

      用以下代码替换您的 IngredientSerializer

      class IngredientSerializer(serializers.ModelSerializer):
      quantity = serializers.SerializerMethodField('get_ingredient_quantity')
      
      class Meta:
          model = Ingredient
          fields = ['id', 'name', 'calories','quantity']
      
      
      def get_ingredient_quantity(self, obj):
          quantity = RecipeIngredient.objects.get(ingredient=obj).quantity
          return quantity
      

      【讨论】:

        猜你喜欢
        • 2019-01-16
        • 2016-05-04
        • 2017-05-24
        • 2016-07-28
        • 1970-01-01
        • 2010-09-29
        • 1970-01-01
        • 2015-07-20
        • 1970-01-01
        相关资源
        最近更新 更多