DRF中MultiPartParser解析返回参数值为列表 如何转为单个值
问题根因
Django 原生 QueryDict 为了兼容同字段多值的表单提交场景,默认会将所有参数值以列表格式存储,且multipart/form-data传输的内容本身全为字符串类型,所以才会出现你看到的{'code': ['3'], 'gst_rate': ['5']}格式。
解决方案
方案1:直接取值转换(最简便,适合字段少的场景)
QueryDict的get()方法和下标取值默认已经会自动取列表的第一个元素,你只需要额外做类型转换即可:
@api_view(['GET','POST','PUT']) @parser_classes([MultiPartParser,JSONParser]) def item_view(request): code = int(request.data.get('code')) gst_rate = int(request.data.get('gst_rate')) # 后续业务逻辑
方案2:使用DRF序列化器(最规范,推荐生产环境使用)
DRF序列化器会自动完成单值提取、类型转换、参数校验的工作,不需要手动处理:
- 先定义序列化器
from rest_framework import serializers class ItemSerializer(serializers.Serializer): code = serializers.IntegerField() gst_rate = serializers.FloatField() # 按需替换为IntegerField也可
- 视图中调用序列化器
@api_view(['GET','POST','PUT']) @parser_classes([MultiPartParser,JSONParser]) def item_view(request): serializer = ItemSerializer(data=request.data) serializer.is_valid(raise_exception=True) # 验证通过后的数据就是你要的格式 print(serializer.validated_data) # 输出 {'code':3, 'gst_rate':5} # 后续业务逻辑
方案3:自定义MultiPartParser(全局统一处理,适合大量接口需要相同逻辑的场景)
如果要让所有使用MultiPartParser的接口默认返回拆包后的值,可以重写解析器:
from rest_framework.parsers import MultiPartParser class CustomMultiPartParser(MultiPartParser): def parse(self, stream, media_type=None, parser_context=None): result = super().parse(stream, media_type, parser_context) # 处理QueryDict,把长度为1的列表拆成单个值 parsed_data = {} for k, v in result.data.items(): if isinstance(v, list) and len(v) == 1: parsed_data[k] = v[0] else: parsed_data[k] = v result.data = parsed_data return result
然后把视图的parser_classes换成你自定义的解析器即可:
@api_view(['GET','POST','PUT']) @parser_classes([CustomMultiPartParser,JSONParser]) def item_view(request): # 此时request.data就已经是拆完单值的格式,自己按需转类型即可
内容的提问来源于stack exchange,提问作者skg_9
相关产品推荐
相关产品推荐

