我们用访问网页动态数据时,经常会提交一些参数,比如用axios.get
:
axios.get('https://example.com/api/users', {
params: {
id: 123,
name: 'foo',
}
});
如果后台程序是 django ,我们可以直接用 request.GET 来访问到这些参数:
def callback(request):
id = request.GET["id"]
name = request.GET["name"]
这里想说的是,如果上传的是一个数组或者多维数组或者一个对象时,问题是什么样子,以及后台程序如何处理。假设:
axios.get('https://example.com/api/users', {
params: {
id: 0,
ids: [1, 2, 3],
two: [[5, 6, ], [7, 8]],
obj: {
a: 9,
b: [10, 11],
},
}
});
此时axios
实际提交的的数据是:
{
"id": 0,
"ids[]": 1
"ids[]": 2
"ids[]": 3
"two[0][0]": 5
"two[0][1]": 6
"two[1][0]": 7
"two[1][1]": 8
"obj[a]": 9
"obj[b][0]": 10
"obj[b][1]": 11
}
从中可以发现规律,如果是一个纯数组,网页上传时会上传重复的ids[]
参数。对于其它更复杂的对象或多维数据,上传的名字为name[key1][key2]...
的形式,直到访问到对象最底层的普通数据。
对前者,django.request
提供了很便捷的访问方法,getlist
函数。它没有副作用,即使用户只上传了一个数据,该函数也不会出错,返回只有一个元素的列表:
def callback(request):
ids = request.GET.getlist("ids[]") # ids = ["1", "2", "3"]
id = request.GET.getlist("id") # id = ["0"]
id1 = request.GET["ids[]"] # works
# id1 = "3",返回最后一个值
对后者, django 是不会自动复原原来的对象和多维数组等多层次结构的,只能手工一个一个字段地获取数据进行拼接:
def callback(request):
obj = {
"a": request.GET["obj[a]"],
"b": [request.GET["obj[b][0]"], request.GET["obj[b][1]"]
}
这种方法过于复杂了,所以更佳的处理方式是 json 序列化和反序列化。前端使用JSON.stringify
的示例如下:
axios.get('https://example.com/api/users', {
params: {
ids: [1, 2, 3],
obj: JSON.stringify({
a: 9,
b: [10, 11],
}),
}
});
后端使用json.loads
解包:
import json
def callback(request):
obj = json.loads(request.GET["obj"])
Q. E. D.