如何在Django中处理多个变量的同一参数的request.GET请求

92

在Django视图中,您可以访问request.GET ['variablename'],因此在您的视图中,您可以像这样执行操作:

myvar = request.GET['myvar']

实际的request.GET['myvar']对象类型是:

<class 'django.http.QueryDict'>

如果您想要传递多个具有相同参数名称的变量,例如:

http://example.com/blah/?myvar=123&myvar=567

您希望在参数 myvar 中返回一个Python list,那么可以尝试以下方法:

for var in request.GET['myvar']:
    print(var)

然而,当你尝试这样做时,你只会得到通过URL传递的最后一个值,例如在上面的示例中,你将获得567,并且在shell中的结果将为:

5
6
7

然而,当你打印request.GET时,它似乎有一个list,即:

<QueryDict: {u'myvar': [u'123', u'567']}>
好的更新: 它被设计为返回最后一个值,我的用例是我需要一个列表。
从 Django 文档中得知:
QueryDict.getitem(key) 返回给定键的值。如果键有多个值,则 getitem() 返回最后一个值。如果键不存在,则引发 django.utils.datastructures.MultiValueDictKeyError(这是 Python 标准 KeyError 的子类,因此您可以继续捕获 KeyError)。
QueryDict.getlist(key) 返回请求键的数据作为 Python 列表。如果键不存在,则返回空列表。它保证返回某种列表。
更新: 如果有人知道 Django 开发人员为什么这样做,请让我知道,似乎与显示列表的方式相矛盾,而且它不像列表那样行为。不太符合 Python 风格!

5
我认为这个推理是因为你需要知道是否期望一个列表或单独的值。QueryDict.getitem不应该有时返回一个列表,有时返回一个单独的项目 - 否则每个人都必须始终检查它的返回类型以正确处理它。 - jgiles
3个回答

204

您想要获取GET对象的getlist()函数:

request.GET.getlist('myvar')

11
如果你使用jQuery提交项目,可能需要在变量名后面添加一个"[]"字符。 - Danny Staple
3
我知道getlist,但是“[]”让我感到困惑。另外,我有一个朋友叫安迪·斯特普尔,一度让我认为他对Django的了解比我意识到的要多得多。这也让我感到困惑。 - kungphu
1
这个需要张贴在Django文档、Django Rest框架文档上,然后在我的额头反过来再贴一遍。这真的让我猝不及防。 - Anthony Manning-Franklin
似乎Django在那方面有些失误,不确定是否有意为之。 - NaturalBornCamper

1
另一个解决方案是创建请求对象的副本... 通常情况下,您不能遍历请求对象的request.GET或request.POST属性,但您可以在其副本上执行此类操作:
res_set = request.GET.copy()
for item in res_set['myvar']:
    item
...

2
你确定吗?这对我并没有改变QueryDict的行为。我只是得到了另一个具有相同“限制”的QueryDict。 - nuts

1

当从包含同一参数的多个值(例如一组复选框)的QueryDict对象创建查询字符串时,请使用urlencode()方法:

例如,我需要获取传入的查询请求,删除一个参数并返回更新后的查询字符串到结果页面。

# Obtain a mutable copy of the original string
original_query = request.GET.copy()

# remove an undesired parameter
if 'page' in original_query:
    del original_query['page']

现在,如果原始查询对于同一参数具有多个值,例如:{...'track_id': ['1', '2'],...} 当使用以下代码时,您将失去查询字符串中的第一个元素:
new_query = urllib.parse.urlencode(original_query)

结果是...
...&track_id=2&...

然而,可以使用QueryDict类的urlencode方法来正确地包含多个值:
new_query = original_query.urlencode()

产生...

...&track_id=1&track_id=2&...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接