我试图弄清楚如何使用Django REST框架保存相关模型。在我的应用程序中,我有一个模型Recipe
,其中包含2个相关模型:RecipeIngredient
和RecipeStep
。一个Recipe
对象必须至少有3个相关的RecipeIngredient
和3个RecipeStep
。在引入REST框架之前,我使用了一个带有两个表单集的Django CreateView
,保存过程如下(遵循form_valid()
的代码):
def save_formsets(self, recipe):
for f in self.get_formsets():
f.instance = recipe
f.save()
def save(self, form):
with transaction.atomic():
recipe = form.save()
self.save_formsets(recipe)
return recipe
def formsets_are_valid(self):
return all(f.is_valid() for f in self.get_formsets())
def form_valid(self, form):
try:
if self.formsets_are_valid():
try:
return self.create_ajax_success_response(form)
except IntegrityError as ie:
return self.create_ajax_error_response(form, {'IntegrityError': ie.message})
except ValidationError as ve:
return self.create_ajax_error_response(form, {'ValidationError': ve.message})
return self.create_ajax_error_response(form)
字符串
现在我有了RecipeViewSet
:
class RecipeViewSet(ModelViewSet):
serializer_class = RecipeSerializer
queryset = Recipe.objects.all()
permission_classes = (RecipeModelPermission, )
型
使用RecipeSerializer
:
class RecipeSerializer(serializers.ModelSerializer):
class Meta:
model = Recipe
fields = (
'name', 'dish_type', 'cooking_time', 'steps', 'ingredients'
)
ingredients = RecipeIngredientSerializer(many=True)
steps = RecipeStepSerializer(many=True)
型
这些是相关的序列化器:
class RecipeIngredientSerializer(serializers.ModelSerializer):
class Meta:
model = RecipeIngredient
fields = ('name', 'quantity', 'unit_of_measure')
class RecipeStepSerializer(serializers.ModelSerializer):
class Meta:
model = RecipeStep
fields = ('description', 'photo')
型
现在......当调用RecipeViewSet
的create()
方法时,我应该如何验证相关模型(RecipeIngredient
和RecipeStep
)并保存它们?(RecipeSerializer
中的is_valid()
实际上忽略了嵌套关系,只报告与主模型Recipe
相关的错误)。目前我试图覆盖RecipeSerializer
中的is_valid()
方法,但不是那么简单...知道吗?
2条答案
按热度按时间h79rfbju1#
这周我处理了类似的问题,我发现django rest framework 3实际上支持嵌套可写序列化(http:www.django-rest-framework.org/topics/3.0-announcement/#serializers在子章节Writable nested serialization中)。
我不确定嵌套序列化器是否是可写的,所以我声明了它们:
字符串
你应该在RecipeSerializer中重写你的create methon:
型
如果这个结构Step.objects.create(recipe=recipe,**step)不起作用,也许您必须从steps_data / ingredients_data中分别选择表示每个字段数据。
这是我之前在堆栈上的问题/答案的链接:How to create multiple objects (related) with one request in DRF?
6ojccjat2#
我想我知道答案了。
字符串
重写to_internal_value()很重要。函数is_valid()有问题。因此,函数中对_internal_value()的每一个更改都在函数is_valid()之前