通过模型Django

时间:2019-05-23 12:35:24

标签: python django many-to-many serializer

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

这是我的模型。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来检索成分的数量,但是我如何在序列化器中包括该字段,以及在哪一个中呢?

2 个答案:

答案 0 :(得分:2)

按如下所示在您的 chunksize = 10 ** 6 for chunk in pd.read_csv(filename, chunksize=chunksize): process(chunk) 中使用SerializerMethodField

IngredientSerializer

答案 1 :(得分:1)

用以下代码替换您的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