Login

get_querystring template tag

Author:
skam
Posted:
February 9, 2015
Language:
Python
Version:
1.7
Tags:
template templatetag querystring
Score:
0 (after 0 ratings)

A Django Template tag used to construct urls with current querystring parameters. This is based on some code that I've written some years ago. Enjoy.

 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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
from django import template
from django.http import QueryDict
from django.utils.safestring import mark_safe
from django.template.loader import get_template
 

register = template.Library()

 
class QueryStringNode(template.Node):
    def __init__(self, to_add, to_remove):
        self.to_add = to_add
        self.to_remove = to_remove
 
    def render(self, context):
        if 'request' not in context:
            raise template.TemplateSyntaxError(
                "'django.core.context_processors.request' not in TEMPLATE_CONTEXT_PROCESSORS"
            )
        querydict = context['request'].GET.copy()
        return self.get_querystring(querydict, self.to_add, self.to_remove, context)
 
    def parse_to_remove(self, to_remove):
        if not to_remove:
            return []
        return [r.strip() for r in to_remove.strip('"').split(',')]
 
    def parse_to_add(self, to_add):
        kw = {}
        to_add = to_add.strip('"')
        if to_add == '':
            return kw
        for a in to_add.split(','):
            k, v = a.strip().split('=')
            kw[k] = v
        return kw
 
    def get_querystring(self, querydict, to_add, to_remove, context):
        new_querydict = QueryDict(querydict.urlencode(), mutable=True) 
        try:
            to_add = self.parse_to_add(to_add)
            to_remove = self.parse_to_remove(to_remove)
        except ValueError:
            raise template.TemplateSyntaxError("Unable to parse arguments")
 
        for r in to_remove:
            try:
                del new_querydict[r]
            except KeyError:
                pass
 
        for k, v in to_add.items():
            if v.startswith('ctx:'):
                v = v.replace('ctx:', '')
                try:
                    value = template.Variable(v).resolve(context)
                except template.VariableDoesNotExist:
                    value = None
                if value:
                    new_querydict[k] = value
            else:
                new_querydict[k] = v
 
        return new_querydict.urlencode()
 
 
@register.tag
def get_querystring(parser, token):
    """
    First argument contains a list of variables that will be added to querystring.
    If value starts with "ctx:", the value will be taken from template context::

        {% get_querystring "pk=ctx:object.pk,a=1" %}

    Second (optional) argument contains a list of variables that will be removed 
    from the querystring::

        {% get_querystring "pk=ctx:object.pk,a=1" "b,c" %}
    """
    bits = token.split_contents()
    if len(bits) < 2:
        raise template.TemplateSyntaxError("%s takes at least one argument" % bits[0])
    to_add = bits[1]
    try:
        to_remove = bits[2]
    except IndexError:
        to_remove = None
    return QueryStringNode(to_add, to_remove)

More like this

Comments

Please login first before commenting.