Login

Querystring Builder - create urls with GET params

Author:
jibberia
Posted:
January 22, 2011
Language:
Python
Version:
1.2
Score:
0 (after 0 ratings)

Save the code as app_name/templatetags/urlbuilder.py. Supply your view with a dictionary of "default" query params, likely taken from the request. Then, in the template:

{% load urlbuilder %} {% url some-url as base_url %}

That sets you up. Then you can make links. For example: <th><a href="{% build_url base_url query_params sort=name %}">Name</a></th>

Say query_params has: page: 2, filter: active, sort: id

The above tag would spit out /base/url?page=2&filter=active&sort=name

The tag also has support for using a variable as the replacement key. Say "filter_key" is a variable available to the template with the value "filter": {% build_url base_url query_params filter_key default %}

Using the above example, that would output /base/url?page=2&filter=default&sort=id

 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
from django import template

register = template.Library()

class QuerystringNode(template.Node):
    def __init__(self, base_url, query_params, override, var_value=None):

        self.base_url = template.Variable(base_url)
        self.query_params = template.Variable(query_params)
        if var_value is not None: # a variable was passed in instead of a literal
            self.var_value = template.Variable(var_value)
        else:
            self.var_value = None
        self.override = override
    
    def render(self, context):
        base_url = self.base_url.resolve(context)
        url = base_url + '?'
        
        if self.var_value is not None:
            var_value = self.var_value.resolve(context)
            k = self.override
            v = var_value
        else:
            k,v = self.override.split('=')
        
        params = self.query_params.resolve(context).copy()
        params[k] = v
        
        # TODO url encode. meh
        for k,v in params.iteritems():
            url += "%s=%s&" % (k,v)
        return url[:-1]


@register.tag
def build_url(parser, token):
    """
    Entry point for the build_url template tag. This tag allows you to maintain
    a set of default querystring parameters and override an individual param.
    
    It was written to support list views that need to keep sort, filter, and page
    parameters, and this is the most common use case.
    
    Usage:
    
        {% build_url base_url query_params override_key=override_value_literal %}
        
                  base_url: string variable -- the URL's prefix
                            try {% url some-url as base_url %}
              query_params: dictionary of default querystring values.
                            {'k1':'v1', 'k2':'mountain'}
                            -> ?k1=v1&k2=mountain
              override_key: key to replace in query_params when building the url.
    override_value_literal: literal (string pls) value for the override
                  (output): (string) the url
    
    There is a second form which allows you to pass in a variable
    for the override value:
    
        {% build_url base_url query_params override_key override_value_variable %}
                                                       ^ that's the difference
    """
    try:
        args = token.split_contents()
        
        base_url = args[1]
        query_params = args[2]
        override = args[3]
        
        var_value = None
        if len(args) == 5:
            var_value = args[4]
    except ValueError:
        raise template.TemplateSyntaxError, "%r tag requires 3 or 4 arguments" % token.contents.split()[0]

    return QuerystringNode(base_url, query_params, override, var_value)

More like this

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

Comments

Please login first before commenting.