我正在django-rest-framework中为我的移动应用程序创建Rest API。我的应用程序与MyFitnessPal相似,因此我的用户有自己的饮食记录,他们的餐食在哪里,每餐都有食物清单。
现在,当我注册用户时,我正在为他创建一个新的空FoodHistory。
因此,接下来我要添加选项以添加/更新这些餐点。当用户想将食品添加到日期为10-10.2019的“早餐”时,我想检查用户历史记录中是否已存在该日期的膳食“早餐”。如果不是,则创建它(并将“ meal_date”参数设置为请求中的日期),如果是,则使用其ID(已创建)获取食品表单DB,并使用“ food_weight”参数将其添加到用户的历史记录中。
当我有多个ManyToMany并通过关系时,我不知道该怎么做。我知道我必须重写serializers.py中的“ create”和“ update”方法以及“ api.py”中的“ post”方法,但是现在我什至不确定哪个序列化程序应该在我的APIView(api.py)类中作为“ serializer_class”。
models.py
class Food(models.Model):
name = models.CharField(max_length=255)
brand = models.CharField(max_length=255, default="")
energy_value = models.DecimalField(max_digits=6, decimal_places=3)
fats = models.DecimalField(max_digits=6, decimal_places=3)
saturated_fats = models.DecimalField(
max_digits=6, decimal_places=3, default=0)
carbohydrates = models.DecimalField(max_digits=6, decimal_places=3)
sugars = models.DecimalField(max_digits=6, decimal_places=3, default=0)
proteins = models.DecimalField(max_digits=6, decimal_places=3)
salt = models.DecimalField(max_digits=6, decimal_places=3, default=0)
class MealType(ChoiceEnum):
BF = "Breakfast"
BR = "Brunch"
DN = "Dinner"
LN = "Lunch"
SU = "Supper"
class Meal(models.Model):
food = models.ManyToManyField(Food, through='FoodDetails')
meal_type = EnumChoiceField(enum_class=MealType, null=True)
class FoodDetails(models.Model):
meal = models.ForeignKey(Meal, on_delete=models.CASCADE)
food = models.ForeignKey(Food, on_delete=models.CASCADE)
food_weight = models.DecimalField(
max_digits=6, decimal_places=3, default=100)
class UserFoodHistory(models.Model):
meal = models.ManyToManyField(Meal, through='MealDate')
class MealDate(models.Model):
user_food_history = models.ForeignKey(
UserFoodHistory, on_delete=models.CASCADE)
meal = models.ForeignKey(Meal, on_delete=models.CASCADE)
meal_date = models.DateField(default=timezone.now, null=True)
class AppUser(AbstractUser):
food_history = models.ForeignKey(
UserFoodHistory, on_delete=models.CASCADE, null=True)
serializers.py
class FoodSerializer(serializers.ModelSerializer):
class Meta:
model = Food
fields = '__all__'
class FoodDetailsSerializer(serializers.ModelSerializer):
food = serializers.ReadOnlyField(source='food.id')
class Meta:
model = FoodDetails
fields = ('id', 'food', 'food_weight')
class MealSerializer(serializers.ModelSerializer):
food = FoodDetailsSerializer(source='fooddetails_set', many=True)
class Meta:
model = Meal
fields = ('id', 'meal_type', 'food')
class MealDateSerializer(serializers.ModelSerializer):
meal = serializers.ReadOnlyField(source='meal.id')
class Meta:
model = MealDate
fields = ('id', 'meal', 'meal_date')
class UserFoodHistorySerializer(serializers.ModelSerializer):
meal = MealDateSerializer(source='mealdate_set', many=True)
class Meta:
model = UserFoodHistory
fields = ('id', 'meal')
class UserSerializer(serializers.ModelSerializer):
food_history = UserFoodHistorySerializer()
class Meta:
model = AppUser
fields = ('id', 'username', 'email', 'food_history')
我想用类似这样的东西做POST请求:
{
"user_id": 1,
"meal_date": "10-10-2019",
"meal_type": "BR",
"food_id": 12,
"food_weight": 120
}
现在我只能通过管理面板创建所有内容,作为响应,它看起来还可以:
{
"id": 2,
"username": "kom1",
"email": "kom1@wp.pl",
"food_history": {
"id": 1,
"meal": [
{
"id": 1,
"meal": 1,
"meal_date": "2019-10-11"
},
{
"id": 2,
"meal": 6,
"meal_date": "2019-10-11"
},
{
"id": 3,
"meal": 2,
"meal_date": "2019-10-11"
},
{
"id": 4,
"meal": 3,
"meal_date": "2019-10-11"
},
{
"id": 5,
"meal": 4,
"meal_date": "2019-10-11"
},
{
"id": 6,
"meal": 5,
"meal_date": "2019-10-11"
}
]
}
}
答案 0 :(得分:0)
您的序列化程序类必须包含模型 MealDate ,并使用APIVIEW创建自定义的 post 方法。 首先,创建 UserFoodHistory 实例,然后在 MealDate 中创建一个批量条目,并在 user_food_history 字段中传递该实例。
在发布API中传递旧ID和新ID,然后从请求中传递,并在APIVIEW中删除 MealDate 中的旧条目(如果存在)并创建一个新条目。