Django - 在不包含某个变量的情况下重建查询字符串

10 投票
2 回答
9001 浏览
提问于 2025-04-16 12:02

我有一个Django的视图,它处理GET请求。我想重建查询字符串,包含所有的变量,除了一个。

我最开始是用列表推导式来实现这个功能:

>>> from django.http import QueryDict
>>> q = QueryDict('a=2&b=4&c=test') // <--- make believe this is request.GET
>>> z = QueryDict('').copy()
>>> z.update(dict([x for x in q.items() if x[0] != 'b']))
>>> z.urlencode()

但我觉得这可能有更好的解决方案:

>>> from django.http import QueryDict
>>> q = QueryDict('a=2&b=4&c=test') // <--- make believe this is request.GET
>>> z = q.copy()
>>> del z['b']
>>> z.urlencode()

有没有人能想到更好的方法呢?

2 个回答

5

最好的方法真的是没得说。我一直以为你第二个(较低的)例子是最新的,搞得我很困惑。

我根本想象不出其他方法,除非我们开始做一些不该做的事情,比如把 _mutable 属性设置为 False,而不是用 copy()

注意:这只是开玩笑,别真的这么做

2110003 次函数调用,耗时 2.117 秒的 CPU 时间

def test3(n):
    for i in range(n):
        q = QueryDict('a=2&b=4&c=test') # we could pass the mutable argument here 
        # but normally we wouldn't be constructing the querydict ourselves
        q._mutable = True
        del q['b']
        q.urlencode()

3010003 次函数调用,耗时 3.065 秒的 CPU 时间

 def test1(n):
    for i in range(n):
        q = QueryDict('a=2&b=4&c=test')
        z = q.copy()
        del z['b']
        z.urlencode()

2860003 次函数调用,耗时 3.388 秒的 CPU 时间

def test2(n):
    for i in range(n):
        q = QueryDict('a=2&b=4&c=test')
        z = QueryDict('').copy()
        z.update(dict([x for x in q.items() if x[0] != 'b']))
        z.urlencode()
12

Django会把GET请求中的变量放进一个字典里,所以你可以直接用request.GET,这个已经是一个QueryDict了。你只需要这样做:

z = request.GET.copy()
del z['a']

需要注意的是,Python中的字典(还有Django的QueryDict)没有del()这个方法,你得用Python自带的del()函数。QueryDict是不可变的(但它的副本是可以变的),所以在你尝试删除之前,复制它是对的。此外,在你最后一行中,z.urlencode()返回的是一个字符串,它并不会把z转换成一个URL编码的字符串,所以你需要把它赋值给另一个变量,这样你才能后续使用。

希望这些能帮到你。

撰写回答