如何在DRF中实现支持多模型数据的POST接口,配合React Axios发起请求
实现方案
完全可以通过DRF嵌套序列化实现单请求同时创建Recipe和关联的Step数据,按以下步骤修改即可:
1. 调整模型层添加反向关联
首先修改models.py中Step模型的外键字段,添加反向关联名,方便序列化器读取关联的步骤数据:
# models.py 仅需修改Step的外键字段部分 class Step(models.Model): step = models.CharField(max_length=300) # 新增related_name参数,值要和后续序列化器里的嵌套字段名对应 uuid = models.ForeignKey(Recipe, on_delete=models.CASCADE, related_name='steps') def __str__(self): return f'{self.step} - {self.uuid}'
注:Step模型中外键命名为uuid容易产生歧义,建议后续迭代改为recipe更符合语义,本次适配保留原有命名
2. 改造序列化器支持嵌套写入
修改serializers.py,给RecipeSerializer添加嵌套的Step序列化字段,并重写create方法实现关联数据的批量写入:
# serializers.py from rest_framework import serializers from .models import * class StepSerializer(serializers.ModelSerializer): class Meta: model = Step fields = ['step'] # 这里不需要带uuid,后续创建时会自动关联赋值 class RecipeSerializer(serializers.ModelSerializer): # 新增嵌套steps字段,支持接收多个step数据 steps = StepSerializer(many=True) class Meta: model = Recipe fields = ['title', 'uuid', 'steps'] def create(self, validated_data): # 先把steps数据从校验后的参数里取出来 steps_data = validated_data.pop('steps') # 先创建Recipe实例 recipe = Recipe.objects.create(**validated_data) # 遍历steps数据,逐个创建Step实例并关联到刚创建的Recipe for step_data in steps_data: Step.objects.create(uuid=recipe, **step_data) return recipe
3. 新增POST接口视图
在views.py中添加创建Recipe的POST视图:
# views.py 新增以下代码 @api_view(['POST']) def recipeCreate(request): serializer = RecipeSerializer(data=request.data) # 校验数据格式合法 if serializer.is_valid(): serializer.save() return Response(serializer.data, status=201) # 校验失败返回错误信息 return Response(serializer.errors, status=400)
记得在urls.py中添加对应路由,比如:
path('recipe-create/', views.recipeCreate, name='recipe-create')
4. 请求示例
接口接收的JSON格式如下:
{ "title": "番茄炒蛋", "uuid": "rec-tomato-egg-001", "steps": [ {"step": "鸡蛋打散加少许盐搅匀"}, {"step": "番茄切滚刀块备用"}, {"step": "热油下锅炒鸡蛋盛出备用"}, {"step": "余油炒番茄出沙后加鸡蛋翻炒均匀即可"} ] }
调用后会自动创建1条Recipe记录和对应的4条Step记录。
内容的提问来源于stack exchange,提问作者user14653534
相关产品推荐
相关产品推荐

