diff --git a/django/utils/html.py b/django/utils/html.py
index 79b0d6d5af..015bc757bd 100644
--- a/django/utils/html.py
+++ b/django/utils/html.py
@@ -1,7 +1,9 @@
"HTML utilities suitable for global use."
-import re, string
-from django.utils.encoding import force_unicode
+import re
+import string
+import urllib
+from django.utils.encoding import force_unicode, smart_str
from django.utils.functional import allow_lazy
# Configuration for urlize() function
@@ -123,3 +125,22 @@ def clean_html(text):
return text
clean_html = allow_lazy(clean_html, unicode)
+def urlquote(url, safe='/'):
+ """
+ A version of Python's urllib.quote() function that can operate on unicode
+ strings. The url is first UTF-8 encoded before quoting. The returned string
+ can safely be used as part of an argument to a subsequent iri_to_uri() call
+ without double-quoting occurring.
+ """
+ return force_unicode(urllib.quote(smart_str(url)))
+urlquote = allow_lazy(urlquote, unicode)
+
+def urlquote_plus(url, safe=''):
+ """
+ A version of Python's urllib.quote_plus() function that can operate on
+ unicode strings. The url is first UTF-8 encoded before quoting. The
+ returned string can safely be used as part of an argument to a subsequent
+ iri_to_uri() call without double-quoting occurring.
+ """
+ return force_unicode(urllib.quote_plus(smart_str(url), safe))
+urlquote_plus = allow_lazy(urlquote_plus, unicode)
diff --git a/tests/regressiontests/text/tests.py b/tests/regressiontests/text/tests.py
index c57ac54078..8cc8e4eeac 100644
--- a/tests/regressiontests/text/tests.py
+++ b/tests/regressiontests/text/tests.py
@@ -16,10 +16,19 @@ r"""
>>> print list(smart_split(r'''all friends' tests'''))[1]
friends'
+### urlquote #############################################################
+>>> from django.utils.html import urlquote, urlquote_plus
+>>> urlquote(u'Paris & Orl\xe9ans')
+u'Paris%20%26%20Orl%C3%A9ans'
+>>> urlquote_plus(u'Paris & Orl\xe9ans')
+u'Paris+%26+Orl%C3%A9ans'
+
### iri_to_uri ###########################################################
>>> from django.utils.encoding import iri_to_uri
>>> iri_to_uri(u'red%09ros\xe9#red')
'red%09ros%C3%A9#red'
>>> iri_to_uri(u'/blog/for/J\xfcrgen M\xfcnster/')
'/blog/for/J%C3%BCrgen%20M%C3%BCnster/'
+>>> iri_to_uri(u'locations/%s' % urlquote_plus(u'Paris & Orl\xe9ans'))
+'locations/Paris+%26+Orl%C3%A9ans'
"""