Django HTTP 请求 get 与 getlist 的行为
我有一个Django表单,它会把一系列值提交到我的视图里。最开始我尝试用get方法来获取这个列表,但发现它只返回了最后一个值,后来才知道应该用getlist。经过一番摸索,我找到了一条已经关闭的Django bug,里面解释了这种行为的原因:
原因是,API方法应该始终返回字符串或列表,但不能同时返回两者。在网页应用中,表单的键通常只对应一个值,所以用[]这种语法来处理。而getlist()则是为了那些像你这种情况,想要用同一个键多次来获取多个值的场景。
我只是想知道这是否真的是一种最佳实践,因为它和其他数据结构,比如字典的get方法的工作方式是相矛盾的。
1 个回答
10
HTTP请求确实支持一个参数(键)可以有多个值。这就是为什么人们可以使用它们,并且有时候确实会使用它们。这也是Django引入了MultiValueDict
结构的原因。
把get()
和getlist()
分开使用是有好处的,因为这样可以帮助你避免错误,并保持你的视图代码简单。想想其他的做法,它们都需要更多的代码来完成完全相同的事情:
get()
总是返回一个列表。在大多数情况下,你只会给一个键传一个值,所以你需要加上
[0]
并提供一个默认值作为列表。param = request.GET.get('param', ['default value',])[0]
get()
根据值的数量返回单个值或列表。
在HTML的选择框中,如果允许选择多个选项,这就成了一个问题。人们可以选择零个、一个或多个值。这意味着你需要自己把单个值转换成列表,或者反过来:
params = request.GET.get('params', [])
# Here you have absolutely no idea if this is a list or a single value
# But you will need only one of that types
# If you need list: ---------------------------------
if not isinstance(params, list):
params = [params,]
objs = TestModel.objects.filter(id__in=params).all()
# If you need single value: -------------------------
if isinstance(params, list):
params = params[0] # Error if params is empty list...
obj = TestModel.objects.get(id=params)
get()
总是返回单个值。那么在这种情况下,如果没有getlist
,你该如何处理多个值呢?
所以,回答你的问题,get/getlist
的行为是有额外价值的。