如何在Django Rest Framework中发送含JSON对象列表的POST请求
解决DRF中POST请求嵌套对象列表的问题
1. 修正模型关系
当前Machine_Learning_Test_Engine中的user_params是外键,意味着一个测试引擎只能关联一个用户参数,但你的请求需要传递多个用户参数,所以需要把外键关系反转到User_Parameters模型中:
# models.py from django.db import models from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ class User_Parameters(models.Model): def validate_standard_deviation_number(value): if value not in range(1,4): raise ValidationError( _('%(value)s is not in range: [1-3]'), params={'value': value}, ) def validate_direction(value): # 0 - Negative, 1 - Positive if value not in range(0,2): raise ValidationError( _('%(value)s needs to be either 0 (Negative) or 1 (Positive)'), params={'value': value}, ) standard_deviation = models.IntegerField(default=1, validators=[validate_standard_deviation_number]) direction = models.IntegerField(default=1, validators=[validate_direction]) feature_list = models.CharField(default='', max_length=3000) # 新增外键,关联到Machine_Learning_Test_Engine mlte = models.ForeignKey('Machine_Learning_Test_Engine', on_delete=models.CASCADE, related_name='user_params') def __str__(self): return f"std dev: {self.standard_deviation}, dir: {self.direction}, feature list: {self.feature_list}" class Machine_Learning_Test_Engine(models.Model): model_path = models.CharField(default='', max_length=3000) data_path = models.CharField(default='', max_length=3000) sep = models.CharField(default='', max_length=3000) target_column = models.CharField(default='', max_length=3000) label_column = models.CharField(default='', max_length=3000) function_names = models.CharField(default='', max_length=3000) def __str__(self): return self.model_path
这里related_name='user_params'用于后续从MLTE实例反向获取关联的用户参数列表。
2. 调整序列化器,支持嵌套列表
在MLTE_Serializers_Model中嵌套User_Parameters_Serializer,并设置many=True接收列表数据,同时重写create方法处理嵌套数据的创建逻辑:
# serializer.py from rest_framework import serializers from .models import User_Parameters, Machine_Learning_Test_Engine class User_Parameters_Serializer(serializers.ModelSerializer): class Meta: model = User_Parameters # 排除mlte字段,由MLTE实例自动关联 exclude = ['mlte'] class MLTE_Serializers_Model(serializers.ModelSerializer): # 嵌套序列化器,接收用户参数列表 user_params = User_Parameters_Serializer(many=True) class Meta: model = Machine_Learning_Test_Engine fields = '__all__' # 重写create方法处理嵌套数据 def create(self, validated_data): # 提取用户参数数据 user_params_data = validated_data.pop('user_params') # 创建MLTE主实例 mlte_instance = Machine_Learning_Test_Engine.objects.create(**validated_data) # 循环创建User_Parameters实例并关联到MLTE for param_data in user_params_data: User_Parameters.objects.create(mlte=mlte_instance, **param_data) return mlte_instance
3. 调整视图,传递用户参数到业务逻辑
序列化器保存后,通过mlte_instance.user_params获取关联的用户参数,转换为需要的格式传入generate_data:
# views.py from rest_framework.decorators import api_view from rest_framework import status from rest_framework.response import Response from .serializers import MLTE_Serializers_Model import pandas as pd # 假设你的MLTE类已定义 class MLTE: def __init__(self, model_path, data_path, sep, target_column, label_column): self.model_path = model_path self.data_path = data_path self.sep = sep self.target_column = target_column self.label_column = label_column self.data = pd.DataFrame() # 示例初始化 def generate_data(self, functions, user_params): # 业务逻辑处理,使用传入的user_params pass @api_view(['POST']) def mlte_reqeust(request): if request.method == 'POST': serializer = MLTE_Serializers_Model(data=request.data) if serializer.is_valid(): mlte_instance = serializer.save() # 转换关联的用户参数为字典列表 user_params_list = [ { 'standard_deviation': param.standard_deviation, 'direction': param.direction, 'feature_list': param.feature_list } for param in mlte_instance.user_params.all() ] mlte = MLTE( mlte_instance.model_path, mlte_instance.data_path, mlte_instance.sep, mlte_instance.target_column, mlte_instance.label_column ) functions = str(mlte_instance.function_names).split(",") # 将用户参数列表传入generate_data mlte.generate_data(functions, user_params_list) json_data_pandas = pd.DataFrame.to_json(mlte.data.head()) return Response(json_data_pandas, status=status.HTTP_200_OK) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
关键说明
- 无需重写
User_Parameters_Serializer的create方法,只需在主序列化器MLTE_Serializers_Model中处理嵌套数据的创建逻辑。 - 模型关系调整是核心:因为需求是一个测试引擎对应多个用户参数,所以外键必须放在
User_Parameters中,而非反向。
内容的提问来源于stack exchange,提问作者Rishabh Tyagi
相关产品推荐
相关产品推荐

