from django import template
from django.utils.safestring import mark_safe
import datetime
register = template.Library()
@register.tag
def query_string(parser, token):
"""
Allows you too manipulate the query string of a page by adding and removing keywords.
If a given value is a context variable it will resolve it.
Based on similiar snippet by user "dnordberg".
requires you to add:
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.request',
)
to your django settings.
Usage:
http://www.url.com/{% query_string "param_to_add=value, param_to_add=value" "param_to_remove, params_to_remove" %}
Example:
http://www.url.com/{% query_string "" "filter" %}filter={{new_filter}}
http://www.url.com/{% query_string "page=page_obj.number" "sort" %}
"""
try:
tag_name, add_string,remove_string = token.split_contents()
except ValueError:
raise template.TemplateSyntaxError, "%r tag requires two arguments" % token.contents.split()[0]
if not (add_string[0] == add_string[-1] and add_string[0] in ('"', "'")) or not (remove_string[0] == remove_string[-1] and remove_string[0] in ('"', "'")):
raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
add = string_to_dict(add_string[1:-1])
remove = string_to_list(remove_string[1:-1])
return QueryStringNode(add,remove)
class QueryStringNode(template.Node):
def __init__(self, add,remove):
self.add = add
self.remove = remove
def render(self, context):
p = {}
for k, v in context["request"].GET.items():
p[k]=v
return get_query_string(p,self.add,self.remove,context)
def get_query_string(p, new_params, remove, context):
"""
Add and remove query parameters. From `django.contrib.admin`.
"""
for r in remove:
for k in p.keys():
if k.startswith(r):
del p[k]
for k, v in new_params.items():
if k in p and v is None:
del p[k]
elif v is not None:
p[k] = v
for k, v in p.items():
try:
p[k] = template.Variable(v).resolve(context)
except:
p[k]=v
return mark_safe('?' + '&'.join([u'%s=%s' % (k, v) for k, v in p.items()]).replace(' ', '%20'))
# Taken from lib/utils.py
def string_to_dict(string):
kwargs = {}
if string:
string = str(string)
if ',' not in string:
# ensure at least one ','
string += ','
for arg in string.split(','):
arg = arg.strip()
if arg == '': continue
kw, val = arg.split('=', 1)
kwargs[kw] = val
return kwargs
def string_to_list(string):
args = []
if string:
string = str(string)
if ',' not in string:
# ensure at least one ','
string += ','
for arg in string.split(','):
arg = arg.strip()
if arg == '': continue
args.append(arg)
return args
Comments
Very useful snippet, but as it stands it's vulnerable to a cross-site scripting attack (because the URL variables previously provided by the user are passed through mark_safe with no escaping, apart from replacing space characters). This can be fixed by adding 'import urllib' at the top, and changing line 73 to:
(Also, to be completely correct even when autoescaping is turned off, I suspect it should be using a plain '&' to delimit the arguments and passing it back as an unsafe string for the template layer to escape - but I'll leave that for someone else to confirm...)
#
django.http.QueryDict is your friend
#
How can I pass a python variable within a double quoted argument of the template tag?
Im trying to create the paginator links, next, previous, etc.. In the query string I might have different parameters apart from "page" and thus to iterate from pages I want to modify only this parameter in the query string.. Something like this:
<a href="{% query_string "page={{ next }}" "page" %}"> Next </a>which obviously doesnt work since django interprets what is inside double quotes as literal string, so it doesnt resolve the variable's value.
How can I do this? Do I need to change the templatetag and send an extra argument (the page variable) ?
Cheers
#
Here's a list of other implementations I could find for a Django template tag which modifies the current HTTP GET query string.
On djangosnippets.org:
On Stack Overflow:
On PyPI:
On GitHub:
#
sistem Universitas Kuliah di Fakultas Teknik Biomedis, CTU di Praha.
Universitas tips cepat hamil pendidikan soal ulangan sd meliputi pengajaran, penelitian, dan kegiatan pelayanan sosial, dan itu termasuk tingkat sarjana (kadang-kadang disebut sebagai pendidikan tinggi) dan pascasarjana (atau pascasarjana) kursus teknisi komputer tingkat (kadang-kadang disebut sebagai sekolah pascasarjana). Universitas umumnya terdiri dari beberapa perguruan tinggi. Di Amerika Serikat, perguruan tinggi kursus bahasa inggris murah dapat menjadi pribadi dan independen, seperti Universitas Yale, mereka dapat umum dan Negara diatur, seperti Pennsylvania State Sistem Pendidikan Tinggi, atau mereka dapat mandiri tetapi Negara didanai, cara mendapatkan uang dari internet seperti University of Virginia.
#