Login

Append paramaters to a GET querystring (template tag)

Author:
gregb
Posted:
July 13, 2009
Language:
Python
Version:
1.0
Score:
3 (after 3 ratings)

This tag is designed to facilitate pagination in the case where both the page number and other parameters (eg. search criteria) are passed via GET.

It takes one argument - a dictionary of GET variables to be added to the current url

Example usage:

{% for page_num in results.paginator.page_range %}     
<a href="{% append_to_get p=page_num %}">{{ page_num }}</a>
{% endfor %}

Note that the passed arguments are evaluated within the template context.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
from django import template

register = template.Library()

"""
Decorator to facilitate template tag creation
"""
def easy_tag(func):
    """deal with the repetitive parts of parsing template tags"""
    def inner(parser, token):
        #print token
        try:
            return func(*token.split_contents())
        except TypeError:
            raise template.TemplateSyntaxError('Bad arguments for tag "%s"' % token.split_contents()[0])
    inner.__name__ = func.__name__
    inner.__doc__ = inner.__doc__
    return inner



class AppendGetNode(template.Node):
    def __init__(self, dict):
        self.dict_pairs = {}
        for pair in dict.split(','):
            pair = pair.split('=')
            self.dict_pairs[pair[0]] = template.Variable(pair[1])
            
    def render(self, context):
        get = context['request'].GET.copy()

        for key in self.dict_pairs:
            get[key] = self.dict_pairs[key].resolve(context)
        
        path = context['request'].META['PATH_INFO']
        
        #print "&".join(["%s=%s" % (key, value) for (key, value) in get.items() if value])
        
        if len(get):
            path += "?%s" % "&".join(["%s=%s" % (key, value) for (key, value) in get.items() if value])
        
        
        return path

@register.tag()
@easy_tag
def append_to_get(_tag_name, dict):
    return AppendGetNode(dict)

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

gregb (on July 13, 2009):

Oops, thanks for pointing that out.

#

udfalkso (on April 29, 2010):

Thanks! I was just about to do something similar.

#

quietbob (on July 19, 2010):

Thanks, very handy. Just a note, I had to change line 40 to:

    path += "?%s" % get.urlencode()

to get things to work correctly in the presence of QueryDicts with multiple values for the same key.

#

quietbob (on July 19, 2010):

Thanks, very handy. Just a note, I had to change line 40 to:

    path += "?%s" % get.urlencode()

to get things to work correctly in the presence of QueryDicts with multiple values for the same key.

#

kneufeld (on April 29, 2011):

You need to have the request context processor.

TEMPLATE_CONTEXT_PROCESSORS = (
...
'django.core.context_processors.request',
...
)

#

peroksid (on December 16, 2012):

class AppendGetNode(template.Node): def init(self, d): self.dict_pairs = [] for pair in d.split(','): k, v = pair.split('=') self.dict_pairs.append((k, template.Variable(v)))

def render(self, context):
    request = context['request']
    get = request.GET.copy()
    for k, v in self.dict_pairs:
        get[k] = v.resolve(context)
    return "%s?%s" % (request.path, get.urlencode())

#

Please login first before commenting.