Django DRF兼容jQuery Ajax与Axios POST接收字符串数组方案
数组参数获取差异原因及跨请求兼容方案
差异根源
- jQuery Ajax发送
application/x-www-form-urlencoded格式的POST请求时,会自动给数组类型的参数键名追加[]后缀,多个数组项会作为同名参数重复提交。因此Django DRF需要用request.data.getlist('something[]')才能完整读取数组。 - Axios默认将JS对象类型的请求体序列化为
application/json格式提交,JSON格式中数组的键名不会追加[]后缀,DRF解析JSON后request.data['something']本身就是数组类型,不需要调用getlist方法,因此原有读取something[]的代码会报错。
如果Axios配置为发送application/x-www-form-urlencoded格式的请求,其默认的数组序列化规则也不会给键名加[]后缀,和jQuery的规则不兼容。
后端兼容方案
我们可以封装一个通用的数组参数读取方法,自动适配两种请求的参数格式:
def get_array_param(request, key: str, default: list = None): """ 从DRF请求中读取数组参数,同时兼容jQuery Ajax和Axios的提交格式 :param request: DRF请求对象 :param key: 数组参数的键名(不带[]后缀) :param default: 参数不存在时返回的默认值 :return: 数组参数 """ default = default if default is not None else [] # 适配Axios JSON格式的参数 if key in request.data: val = request.data[key] return val if isinstance(val, list) else [val] # 适配jQuery Ajax的表单格式参数 form_key = f"{key}[]" if form_key in request.data: return request.data.getlist(form_key) return default
使用方法非常简单,只要在需要读取数组的位置调用即可:
# 例如读取something数组 something_list = get_array_param(request, "something")
如果不想修改后端代码,也可以在前端Axios侧配置序列化规则,让其对齐jQuery的数组提交格式:
import qs from 'qs' // 全局配置Axios数组序列化规则 axios.defaults.paramsSerializer = function(params) { return qs.stringify(params, { arrayFormat: 'brackets' }) }
配置后Axios发送数组参数时会自动追加[]后缀,原有后端代码不需要修改即可正常读取。
内容的提问来源于stack exchange,提问作者Adrian0012
相关产品推荐
相关产品推荐

