Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - Rebuild a query string without one of the variables

I have a Django view that processes a GET request. I want to rebuild the query string to include all variables except for one.

I was initially using list comprehension:

>>> 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()

But I believe this may be a better solution:

>>> 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()

Can anyone think of an even better approach?

like image 971
Belmin Fernandez Avatar asked Feb 18 '11 00:02

Belmin Fernandez


2 Answers

Django puts the GET request variables into a dictionary for you, so request.GET is already a QueryDict. You can just do this:

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

Note that dictionaries in python (and django QueryDicts) don't have a del() method, you have to use python's built in del() function. QueryDicts are immutable (but copies of them are not), so you were right to copy it before trying to delete from it. Also, in your last line z.urlencode() returns a string, it doesn't convert z to a url encoded string, so you need to assign it to another variable in order to do something with it later.

Hope that helps

like image 115
danny Avatar answered Oct 15 '22 14:10

danny


The top approach is definitely as good as it gets. I kept thinking your second (lower) example was your newest one and was thoroughly confused.

I can't even imagine another method unless we start doing stuff we're not supposed todo, like setting the _mutable attribute to False instead of copy().

Note: this is for shits and giggles, don't actually do this

2110003 function calls in 2.117 CPU seconds

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 function calls in 3.065 CPU seconds

 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 function calls in 3.388 CPU seconds

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()
like image 21
Yuji 'Tomita' Tomita Avatar answered Oct 15 '22 14:10

Yuji 'Tomita' Tomita