在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
相关产品推荐
相关产品推荐

