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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104 | """
Templatetags for generating query string modifying the current request's query
string.
version: 0.2
"""
from django import template
from django.utils.datastructures import MultiValueDict
register = template.Library()
def _unquote(str, required=True, error_msg=''):
"""
Strips the quotes from a string, I find it useful after parsing tags with
split_contents().
"""
if str[0] == str[-1] and str[0] in ('"',"'"):
return str[1:-1]
else:
if required:
raise TemplateSyntaxError, error_msg
return str
def dict_from_qstring(qstring):
"""
Returns a MultiValueDict from a query string.
"""
mvd = MultiValueDict()
for item in qstring.split('&'):
sp = item.split('=')
if len(sp) == 1:
value = None
elif len(sp) == 2:
value = sp[1]
else:
continue
mvd.appendlist(sp[0], value)
return mvd
def qstring_from_dict(mvd):
"""
Returns a query string from a MultiValueDict.
"""
tmp = []
for key, values in mvd.lists():
for value in values:
tmp.append('='.join([key, str(value)]))
return '&'.join(tmp)
def tag_from_operation(operation_fn):
"""
Returns a tag function wich uses a operation function (operation_fn).
"""
class Node(template.Node):
def __init__(self, qstring):
self.qstring = qstring
def render(self, context):
mvd = dict_from_qstring(self.qstring)
diff_mvd = operation_fn(context['request'].GET, mvd)
return qstring_from_dict(diff_mvd)
def do_operation(parser, token):
args = token.split_contents()
tag_name = args[0]
qstring = _unquote(args[1], required=True,
error_msg='%r tag\'s argument should '
'be in quotes.' % tag_name)
return Node(qstring)
return do_operation
def delete(lmvd, rmvd):
mvd = lmvd.copy()
for key, value in rmvd.lists():
if key in mvd:
if None in value:
new_list = []
else:
new_list = [i for i in mvd.getlist(key) if i not in value]
mvd.setlist(key, new_list)
return mvd
register.tag('qs_delete', tag_from_operation(delete))
def update(lmvd, rmvd):
mvd = lmvd.copy()
for key, values in rmvd.lists():
if key in mvd:
mvd.setlist(key, values)
return mvd
register.tag('qs_update', tag_from_operation(update))
|
Comments