我正在研究“嵌套嵌套”序列化器,其中有一个嵌套的序列化器嵌套在另一个序列化器中。这是一项烹饪服务,其中食谱具有多个方向,每个方向具有多种成分。我用外键进行设置。
这是我的模特:
class Category(models.Model):
"""Model representing a recipe category"""
name = models.CharField(max_length=200, help_text="Enter a recipe category (e.g Baking)")
def __str__(self):
"""String for representing the Model object."""
return self.name
class Ingredient(models.Model):
"""Model representing an ingredient in a direction"""
name = models.CharField(max_length=250, help_text="The ingredient's name")
quantity = models.CharField(max_length=200, help_text="How much of this ingredient.")
direction = models.ForeignKey("Direction", help_text="This ingredient's direction", on_delete=models.CASCADE, related_name='ingredients')
def __str__(self):
"""String for representing this recipe ingredient"""
return f'{self.quantity} {self.ingredient}'
class Direction(models.Model):
"""Model representing a step in a recipe"""
title=models.CharField(max_length=200)
text=models.TextField(blank=True, help_text="Describe this step.")
recipe=models.ForeignKey("Recipe", help_text="This direction's recipe", on_delete=models.CASCADE, related_name='directions')
def __str__(self):
"""String for representing the Direction"""
return self.title
class Recipe(models.Model):
"""Model representing a recipe."""
title = models.CharField(max_length=200)
notes = models.TextField(max_length=1000, help_text="Enter notes, reviews, ...")
photos = models.ImageField(null=True, blank=True)
category = models.ForeignKey(Category, help_text="This recipe's category", on_delete=models.CASCADE, related_name='recipes')
def __str__(self):
"""String for representing the Model object."""
return self.title
def get_absolute_url(self):
"""Returns the url to access a detail record for this recipe."""
我读了docs,以为我可以在另一个嵌套嵌套序列化器中使用,这使我犯了一个错误,指出“禁止直接分配给相关集合的反面。”
然后我通过使用以下序列化程序使其工作:
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ('name',)
def create(self, validated_data):
category = Category.objects.create(**validated_data)
return category
class IngredientSerializer(serializers.ModelSerializer):
class Meta:
model = Ingredient
fields = ('quantity', 'name',)
def create(self, validated_data):
ingredient = Ingredient.objects.create(**validated_data)
return ingredient
def update(self, instance, validated_data):
instance.quantity = validated_data.get('quantity', instance.quantity)
instance.name = validated_data.get('name', instance.name)
instance.direction = validated_data.get('direction', instance.direction)
instance.save()
return instance
class DirectionSerializer(serializers.ModelSerializer):
ingredients = IngredientSerializer(many=True)
class Meta:
model = Direction
fields = ('title', 'text', 'ingredients', )
def create(self, validated_data):
direction = Direction.objects.create(**validated_data)
return direction
def update(self, instance, validated_data):
instance.title = validated_data.get('title', instance.title)
instance.text = validated_data.get('text', instance.text)
instance.recipe = validated_data.get('recipe', instance.recipe)
instance.save()
return instance
class RecipeSerializer(serializers.ModelSerializer):
directions = DirectionSerializer(many=True)
category = CategorySerializer()
class Meta:
model = Recipe
fields = ('title', 'notes', 'photos', 'category', 'directions')
def create(self, validated_data):
directions_data = validated_data.pop('directions')
category_data = validated_data.pop('category')
category = Category.objects.create(**category_data)
validated_data["category"] = category
recipe = Recipe.objects.create(**validated_data)
recipe.category = category
for direction_data in directions_data:
ingredients_data = direction_data.pop("ingredients")
direction = Direction.objects.create(recipe=recipe, **direction_data)
for ingredient_data in ingredients_data:
Ingredient.objects.create(direction=direction, **ingredient_data)
return recipe
def update(self, instance, validated_data):
instance.title = validated_data.get('title', instance.title)
instance.notes = validated_data.get('notes', instance.notes)
instance.photos = validated_data.get('photos', instance.photos)
instance.category = validated_data.get('category', instance.category)
instance.save()
return instance
我不确定,在这一点上实际上需要什么。基本上,我在食谱的create()函数中创建嵌套结构。
现在真正的问题是: 感觉确实像黑客一样。这是实现多个嵌套序列化器的正确方法吗?
如果我这样做,我是否还需要create()和update()函数?
非常感谢您。