Ось корисний спеціальний тег шаблону для побудови рядків запитів.
<a href="?{% make_query_string page=obj_list.next_page_number %}">Next page</a>
Якщо URL-адреса http://example.com/django/page/?search=sometext , згенерований HTML повинен бути приблизно таким:
<a href="?search=sometext&page=2">Next page</a>
Інші приклади:
{% make_query_string page=2 item="foo2" size=10 %}
{% make_query_string item+="foo2" item+="bar2" %}
{% make_query_string item-="foo" %}
{% make_query_string item= %}
Нарешті, вихідний код (написаний мною):
from django import template
from django.utils.encoding import force_text
register = template.Library()
class QueryStringNode(template.Node):
def __init__(self, tag_name, parsed_args, var_name=None, silent=False):
self.tag_name = tag_name
self.parsed_args = parsed_args
self.var_name = var_name
self.silent = silent
def render(self, context):
query_dict = context['request'].GET.copy()
for op, key, value in self.parsed_args:
if op == '+':
query_dict.appendlist(key, value.resolve(context))
elif op == '-':
list_ = query_dict.getlist(key)
value_ = value.resolve(context)
try:
list_.remove(value_)
except ValueError:
if not isinstance(value_, basestring):
try:
list_.remove(force_text(value_))
except ValueError:
pass
elif op == 'd':
try:
del query_dict[key]
except KeyError:
pass
else:
query_dict[key] = value.resolve(context)
query_string = query_dict.urlencode()
if self.var_name:
context[self.var_name] = query_string
if self.silent:
return ''
return query_string
@register.tag
def make_query_string(parser, token):
args = token.split_contents()
tag_name = args[0]
as_form = False
if len(args) > 3 and args[-3] == "as":
if args[-1] != "silent":
raise template.TemplateSyntaxError(
"Only 'silent' flag is allowed after %s's name, not '%s'." %
(tag_name, args[-1]))
as_form = True
silent = True
args = args[:-1]
elif len(args) > 2 and args[-2] == "as":
as_form = True
silent = False
if as_form:
var_name = args[-1]
raw_pairs = args[1:-2]
else:
raw_pairs = args[1:]
parsed_args = []
for pair in raw_pairs:
try:
arg, raw_value = pair.split('=', 1)
except ValueError:
raise template.TemplateSyntaxError(
"%r tag's argument should be in format foo=bar" % tag_name)
operator = arg[-1]
if operator == '+':
parsed_args.append(('+', arg[:-1], parser.compile_filter(raw_value)))
elif operator == '-':
parsed_args.append(('-', arg[:-1], parser.compile_filter(raw_value)))
elif raw_value == '':
parsed_args.append(('d', arg, None))
else:
parsed_args.append(('', arg, parser.compile_filter(raw_value)))
if as_form:
node = QueryStringNode(tag_name, parsed_args,
var_name=var_name, silent=silent)
else:
node = QueryStringNode(tag_name, parsed_args)
return node
request
як параметр. Дивіться цей відповідь stackoverflow.com/a/2160298/1272513