有两种方法可以得到这个结果[2] 有另一个模型:
- 使用
WritableNestedModelSerializer。
- 覆盖序列化程序的
create() 方法。
第一个示例,使用WritableNestedModelSerializer:
# models.py --------------------------
class Ingredient(models.Model):
# model that will be related to Meal.
name = models.CharField(max_lenght=128)
amount = models.IntergerField()
def __str__(self):
return str(self.name)
class Meal(models.Model):
# meal model related to Ingredient.
name = models.TextField()
recipe = models.TextField()
ingredients = models.ForeigKey(Ingredient)
def __str__(self):
return str(self.name)
# serializers.py ----------------------
class IngredientSerializer(serializers.ModelSerializer):
class Meta:
model = Ingredient
fields = '__all__'
class MealSerializer(WritableNestedModelSerializer, serializers.ModelSerializer):
ingredients_set = IngredientSerializer(required=False, many=True)
class Meta:
model = Ingredient
fields = ["id", "name","recipe", "ingredients_set"]
第二个示例重写create()方法:
# models.py --------------------------
# Follow the same approach as the first example....
# serializers.py ----------------------
class IngredientSerializer(serializers.ModelSerializer):
class Meta:
model = Ingredient
fields = '__all__'
class MealSerializer(serializers.ModelSerializer):
ingredients = IngredientSerializer(required=False, many=True)
class Meta:
model = Meal
fields = ["id", "name","recipe", "ingredients"]
def create(self, validated_data):
# 1st step.
ingredients = validated_data('ingredients')
# 2nd step.
actual_instance = Meal.objects.create(**validated_data)
# 3rd step.
for ingredient in ingredients:
ing_objects = Ingredients.object.create(**ingredient)
actual_instance.ingredients.add(ing_objects.id)
actua_instance.save()
return actual_instance
第二个例子做了什么?
第一步:由于您创建一对二多关系,端点将等待这样的有效负载:
{
"name": null,
"recipe": null,
"ingredients": [],
}
您发送的数据/已验证数据的前:
{
"id": 1,
"name": "spaghetti",
"recipe": "recipe",
"ingredients": [
{name:'pasta',amount:100},{name:'tomato',amount:200},{...}
],
}
因此,由于您发送的有效载荷包含成分数组中的许多成分,您将从 validated_data 获取此值。
例如,如果您打印'ingredients'(从 create() 方法的内部),您将在终端中得到:
[{name:'pasta',amount:100},{name:'tomato',amount:200},{...}]
第二步:好的,既然您从 validate_data 中获取了成分,那么是时候创建一个 Meal 实例了(其中没有“成分”)。
第 3 步:您将从上述第 1 步中循环所有成分对象,并将它们添加到 Meal.ingredients 关系中以保存 Meal 实例。
-- 关于额外模型--
[2] 请记住,JSONField() 允许在其中添加任何内容,甚至是额外的字段。如果您想要更好地控制,使用 Meal 模型可能是更好的选择。