Skip to content

Instantly share code, notes, and snippets.

@bradwright
Created April 16, 2010 14:36
Show Gist options
  • Save bradwright/368478 to your computer and use it in GitHub Desktop.
Save bradwright/368478 to your computer and use it in GitHub Desktop.
import urllib
try:
from urlparse import parse_qs
except ImportError:
from cgi import parse_qs
def url_params(url, **kwargs):
bits = url.split('?')
query_vars = {}
if len(bits) > 1:
query_vars = parse_qs(bits[1], keep_blank_values=1)
for key, value in query_vars.items():
# value is always a list - kill it as we want to overwrite it
query_vars[key] = value[0]
query_vars.update(kwargs)
new_dict = {}
for key, value in query_vars.items():
# filter out empty values
if str(value) != '0' and not value:
continue
else:
new_dict[key] = value
kwargs = new_dict
query_string = ''
url = bits[0]
if kwargs:
query_string = urllib.urlencode(kwargs)
if query_string:
url = '%s?%s' % (url, query_string)
return url
if __name__ == '__main__':
import unittest
class UrlTest(unittest.TestCase):
def test_single_query_string(self):
"""Tests that a query string is appended correctly"""
new_url = url_params('/something/something', blah='true')
self.assertEqual(new_url, '/something/something?blah=true')
def test_multi_query_string(self):
"""Tests that multiple parameters to a query string are appended"""
new_url = url_params('/something/something', blah='true', something='somethingelse')
self.assertEqual(new_url, '/something/something?blah=true&something=somethingelse')
def test_no_query_string(self):
"""Tests that no query string is valid"""
new_url = url_params('/blah/foo')
self.assertEqual(new_url, '/blah/foo')
def test_existing_query_string(self):
"""Tests that old query strings aren't overwritten"""
new_url = url_params('/blah/foo?thing=other&blah=yes')
self.assertEqual(new_url, '/blah/foo?thing=other&blah=yes')
def test_overwrite_query_string(self):
"""tests that query parameters are overwritten by arguments"""
new_url = url_params('/blah/foo?thing=yes', thing='no')
self.assertEqual(new_url, '/blah/foo?thing=no')
def test_delete_query_string(self):
"""tests that query parameters are deleted by explicitly killing them"""
new_url = url_params('/blah/foo?thing=yes', thing=False)
self.assertEqual(new_url, '/blah/foo')
def test_extra_parameter(self):
"""Tests that extra false parameters don't kill the reverser"""
new_url = url_params('/blah/foo', thing=False)
self.assertEqual(new_url, '/blah/foo')
def test_falsiness(self):
"""Test that only False, empty strings, and None gets dropped"""
new_url = url_params('/blah/foo', thing=None)
self.assertEqual(new_url, '/blah/foo')
new_url = url_params('/blah/foo', thing=False)
self.assertEqual(new_url, '/blah/foo')
new_url = url_params('/blah/foo', thing='')
self.assertEqual(new_url, '/blah/foo')
new_url = url_params('/blah/foo', thing=0)
self.assertEqual(new_url, '/blah/foo?thing=0')
new_url = url_params('/blah/foo', thing=1)
self.assertEqual(new_url, '/blah/foo?thing=1')
unittest.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment