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

在Django DRF中使用Swagger发送工时列表作为多部分数据的问题

解决DRF+drf-spectacular Swagger中multipart/form-data传递嵌套工时列表的问题

一、修复Serializer的写权限与创建逻辑

原FacilitySerializer中workingHours设为read_only=True,导致POST请求无法接收工时数据,需调整并补充批量创建关联数据的逻辑:

# serializers.py
class WorkingHoursSerializer(serializers.ModelSerializer):
    class Meta:
        model = WorkingHours
        fields = ('dayOfWeek', 'startTime', 'endTime')

class FacilitySerializer(serializers.ModelSerializer):
    # 移除read_only=True,允许写入嵌套工时数据
    workingHours = WorkingHoursSerializer(many=True)

    class Meta:
        model = Facility
        fields = ('id', 'name', 'workingHours', 'price', 'phoneNumber', 'coordinates')  # 补充其他需提交的字段

    def create(self, validated_data):
        # 提取工时数据并从主数据中移除
        working_hours_data = validated_data.pop('workingHours')
        # 创建Facility主实例
        facility = Facility.objects.create(**validated_data)
        # 批量创建关联的WorkingHours记录
        WorkingHours.objects.bulk_create([
            WorkingHours(linkedFacility=facility, **wh_data)
            for wh_data in working_hours_data
        ])
        return facility

二、multipart/form-data下的正确请求格式

1. curl命令的正确写法

需将工时列表转为标准JSON字符串,并指定该字段的Content-Type为application/json,同时修正时间格式为合法的HH:MM:SS:

curl -X 'POST' \
  'http://127.0.0.1:8000/api/v1/facilities/' \
  -H 'accept: application/json' \
  -H 'X-CSRFTOKEN: ot91cIAOrwhjDMU0LtAFhAce1vVxODO5JVQqTRrFumPjyHImS6e0dHqDqseqMbVI' \
  -F 'name=first' \
  -F 'price=300' \
  -F 'phoneNumber=+3821312231213' \
  -F 'coordinates=POINT(44.7866 20.4489)' \
  -F 'uploadImages=@1.jpeg;type=image/jpeg' \
  -F 'uploadSearchImage=@2.jpeg;type=image/jpeg' \
  -F 'workingHours=[
    {"dayOfWeek":7,"startTime":"09:00:00","endTime":"18:00:00"},
    {"dayOfWeek":6,"startTime":"10:00:00","endTime":"16:00:00"}
  ];type=application/json'

2. Swagger界面的输入方案

Swagger对multipart嵌套数组的默认支持有限,可选择以下两种方式:

  • 方案一:直接输入JSON字符串
    在Swagger的workingHours输入框中,粘贴完整的JSON数组字符串:
[{"dayOfWeek":7,"startTime":"09:00:00","endTime":"18:00:00"},{"dayOfWeek":6,"startTime":"10:00:00","endTime":"16:00:00"}]
  • 方案二:配置drf-spectacular生成可拆分的表单字段
    修改项目settings.py中的drf-spectacular配置,开启请求拆分功能:
SPECTACULAR_SETTINGS = {
    'COMPONENT_SPLIT_REQUEST': True,
    'SCHEMA_PATH_PREFIX': r'/api/v1/',
    'ENABLE_SWAGGER_UI': True,
    'SWAGGER_UI_SETTINGS': {
        'deepLinking': True,
    },
}

开启后Swagger会将嵌套数组拆分为独立表单项(如workingHours[0].dayOfWeek、workingHours[0].startTime),可直接在界面上逐个输入工时数据。

三、额外注意事项

  • 确保视图类使用CreateAPIView或重写post方法,并绑定修改后的FacilitySerializer。
  • 验证startTime和endTime格式必须为HH:MM:SS,符合DRFTimeField的要求。
  • 带文件上传的视图默认支持multipart/form-data,无需额外配置。

内容的提问来源于stack exchange,提问作者egums

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 18:10:54