Django REST处理form-urlencoded请求返回XML响应配置方法
Django对接支付网关:接收form-urlencoded请求返回XML响应方案
报错根因
- 415错误:之前配置
parser_classes = (XMLParser,)逻辑完全错误。parser_classes负责解析入参格式,支付方传入的是application/x-www-form-urlencoded格式,XMLParser仅能解析XML格式请求体,无法识别入参格式就会抛出415不支持媒体类型错误。 - 406错误:DRF默认仅内置JSON格式响应渲染器,即使手动给Response指定
content_type="application/xml",框架也没有对应的XML序列化能力,无法匹配请求头中Accept: application/xml的要求,就会抛出406不可接受错误。
实现步骤
- 安装XML渲染依赖
DRF官方没有内置XML渲染器,需要先安装对应扩展包:
pip install djangorestframework-xml
- 编写正确的视图逻辑
解析入参使用DRF自带的FormParser适配form-urlencoded格式,出参使用XMLRenderer适配XML响应要求,代码如下:
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.parsers import FormParser from rest_framework_xml.renderers import XMLRenderer class ITNView(APIView): # 入参解析器:匹配application/x-www-form-urlencoded格式 parser_classes = (FormParser,) # 响应渲染器:匹配application/xml格式要求 renderer_classes = (XMLRenderer,) def post(self, request): # request.data已经自动解析完form格式参数,直接取值即可 transaction_body = request.data.get('transaction') print(transaction_body) # 替换为支付服务商要求的实际返回字段结构 response_data = { "code": "SUCCESS", "message": "接收成功" } # 如需自定义XML根节点(多数支付网关要求根节点为<xml>),加root_tag_name参数即可 # return Response(response_data, root_tag_name='xml') return Response(response_data)
注意事项
- 如果后续可能遇到
multipart/form-data格式的请求,可在parser_classes中追加MultiPartParser,配置为parser_classes = (FormParser, MultiPartParser)即可兼容两种表单格式。 - 不需要手动给Response指定
content_type参数,XMLRenderer会自动将响应头设置为application/xml,手动指定反而可能和渲染器逻辑冲突导致格式异常。 - 返回的
response_data字段名、层级必须严格匹配支付服务商的接口文档要求,XMLRenderer会自动将字典序列化为对应XML结构。
内容的提问来源于stack exchange,提问作者xGoldeNx
相关产品推荐
相关产品推荐

