Add urlparams helper from various projects

This commit is contained in:
James Socol
2014-06-24 15:38:58 -04:00
parent ad909e4830
commit 25fc9a79a0
2 changed files with 75 additions and 3 deletions

View File

@@ -2,14 +2,19 @@
from __future__ import unicode_literals, print_function
from django.utils import six
from django.utils.translation import ugettext as _
import urlparse
from django.core.urlresolvers import reverse
from django.http import QueryDict
from django.template.defaulttags import CsrfTokenNode
from django.utils import six
from django.utils.encoding import smart_str
try:
from django.utils.encoding import smart_unicode as smart_text
except ImportError:
from django.utils.encoding import smart_text
from django.core.urlresolvers import reverse
from django.utils.http import urlencode
from django.utils.translation import ugettext as _
import jinja2
@@ -92,3 +97,37 @@ def field_attrs(field_inst, **kwargs):
def url(viewname, *args, **kwargs):
"""Return URL using django's ``reverse()`` function."""
return reverse(viewname, args=args, kwargs=kwargs)
@register.filter
def urlparams(url_, fragment=None, query_dict=None, **query):
"""
Add a fragment and/or query parameters to a URL.
New query params will be appended to exising parameters, except duplicate
names, which will be replaced.
"""
url_ = urlparse.urlparse(url_)
fragment = fragment if fragment is not None else url_.fragment
q = url_.query
new_query_dict = (QueryDict(smart_str(q), mutable=True) if
q else QueryDict('', mutable=True))
if query_dict:
for k, l in query_dict.lists():
new_query_dict[k] = None # Replace, don't append.
for v in l:
new_query_dict.appendlist(k, v)
for k, v in query.items():
# Replace, don't append.
if isinstance(v, list):
new_query_dict.setlist(k, v)
else:
new_query_dict[k] = v
query_string = urlencode([(k, v) for k, l in new_query_dict.lists() for
v in l if v is not None])
new = urlparse.ParseResult(url_.scheme, url_.netloc, url_.path,
url_.params, query_string, fragment)
return new.geturl()

View File

@@ -176,3 +176,36 @@ def test_filter_override():
register.filter(g)
s = render('{{ s|a }}', {'s': 'Str'})
eq_(s, 'str')
def test_urlparams_unicode():
context = {'q': u'Fran\xe7ais'}
eq_(u'/foo?q=Fran%C3%A7ais', helpers.urlparams('/foo', **context))
context['q'] = u'\u0125help'
eq_(u'/foo?q=%C4%A5help', helpers.urlparams('/foo', **context))
def test_urlparams_valid():
context = {'a': 'foo', 'b': 'bar'}
eq_(u'/foo?a=foo&b=bar', helpers.urlparams('/foo', **context))
def test_urlparams_query_string():
eq_(u'/foo?a=foo&b=bar', helpers.urlparams('/foo?a=foo', b='bar'))
def test_urlparams_multivalue():
eq_(u'/foo?a=foo&a=bar', helpers.urlparams('/foo?a=foo&a=bar'))
eq_(u'/foo?a=foo&a=bar', helpers.urlparams('/foo', a=['foo', 'bar']))
eq_(u'/foo?a=bar', helpers.urlparams('/foo?a=foo', a='bar'))
def test_urlparams_none():
"""Assert a value of None doesn't make it into the query string."""
eq_(u'/foo', helpers.urlparams('/foo', bar=None))
def test_urlparams_fragment():
eq_(u'/#foo', helpers.urlparams('/', fragment='foo'))
eq_(u'/#bar', helpers.urlparams('/#foo', fragment='bar'))
eq_(u'/', helpers.urlparams('/#foo', fragment=''))