You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 18:18:29