Skip to content

Instantly share code, notes, and snippets.

@benbacardi
Last active October 11, 2023 11:03
Show Gist options
  • Save benbacardi/d6cd0fb8c85e1547c3c60f95f5b2d5e1 to your computer and use it in GitHub Desktop.
Save benbacardi/d6cd0fb8c85e1547c3c60f95f5b2d5e1 to your computer and use it in GitHub Desktop.
Django query_transform templatetag
from django import template
register = template.Library()
@register.simple_tag(takes_context=True)
def query_transform(context, **kwargs):
'''
Returns the URL-encoded querystring for the current page,
updating the params with the key/value pairs passed to the tag.
E.g: given the querystring ?foo=1&bar=2
{% query_transform bar=3 %} outputs ?foo=1&bar=3
{% query_transform foo='baz' %} outputs ?foo=baz&bar=2
{% query_transform foo='one' bar='two' baz=99 %} outputs ?foo=one&bar=two&baz=99
A RequestContext is required for access to the current querystring.
'''
query = context['request'].GET.copy()
for k, v in kwargs.items():
query[k] = v
return query.urlencode()
@ZoltanOnody
Copy link

line 12; {% query_transform bar=3 %} outputs ?foo=1&bar=3 right?

@benbacardi
Copy link
Author

You're right, thanks! I'll edit it!

@zlove
Copy link

zlove commented Oct 13, 2017

Great solution. For Python 3 compatibility, you might want to update it to use kwargs.items() instead of kwargs.iteritems()

@cursologo-gh
Copy link

the " ? " is getting encode when I use this code. It shows like %3Fprecio=0 (precio being the variable i'm passing)

@kameruchi
Copy link

@cursologo-gh, try using the safe parameter of urlencode.
From django docs: Use safe to pass characters which don’t require encoding. For example:

q = QueryDict(mutable=True)
q['next'] = '/a&b/'
q.urlencode(safe='/')
'next=/a%26b/'
https://docs.djangoproject.com/en/2.1/ref/request-response/#django.http.QueryDict.urlencode

@AdrianMos
Copy link

AdrianMos commented Jun 29, 2019

Great! Tanks! (line 19: for Python 3 rename iteritems() to items())

@Hammy27
Copy link

Hammy27 commented Mar 18, 2021

If you are working with djangos pagination and your template takes care of the page keyword, simply adding

query.pop('page', None)

before returning the query does the trick.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment