summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMattias Loverot <mattias@stubin.se>2016-08-24 18:18:17 +0200
committerClaude Paroz <claude@2xlibre.net>2016-08-24 18:18:17 +0200
commit9aaeec337e217109208672d8fe47eeb49ca492b5 (patch)
tree4b815546bfd3b8a5844464c3cea9d397b792c4c2
parentcf2cd4053fe3eed50ab2b7269ed72d25712c970a (diff)
downloaddjango-9aaeec337e217109208672d8fe47eeb49ca492b5.tar.gz
Fixed #26866 -- Added format_lazy function
Added format_lazy function to django.utils.text module. Useful when dealing with relative complex lazy string concatenations (e.g. in urls.py when translating urls in regular expressions).
-rw-r--r--django/utils/text.py13
-rw-r--r--docs/ref/utils.txt20
-rw-r--r--tests/utils_tests/test_text.py24
3 files changed, 55 insertions, 2 deletions
diff --git a/django/utils/text.py b/django/utils/text.py
index f51113b483..3b8fc581bf 100644
--- a/django/utils/text.py
+++ b/django/utils/text.py
@@ -7,7 +7,9 @@ from io import BytesIO
from django.utils import six
from django.utils.encoding import force_text
-from django.utils.functional import SimpleLazyObject, keep_lazy, keep_lazy_text
+from django.utils.functional import (
+ SimpleLazyObject, keep_lazy, keep_lazy_text, lazy,
+)
from django.utils.safestring import SafeText, mark_safe
from django.utils.six.moves import html_entities
from django.utils.translation import pgettext, ugettext as _, ugettext_lazy
@@ -434,3 +436,12 @@ def camel_case_to_spaces(value):
trailing whitespace.
"""
return re_camel_case.sub(r' \1', value).strip().lower()
+
+
+def _format_lazy(format_string, *args, **kwargs):
+ """
+ Apply str.format() on 'format_string' where format_string, args,
+ and/or kwargs might be lazy.
+ """
+ return format_string.format(*args, **kwargs)
+format_lazy = lazy(_format_lazy, six.text_type)
diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt
index e7b3b2a997..07fa53990e 100644
--- a/docs/ref/utils.txt
+++ b/docs/ref/utils.txt
@@ -868,6 +868,26 @@ appropriate entities.
.. module:: django.utils.text
:synopsis: Text manipulation.
+.. function:: format_lazy(format_string, *args, **kwargs)
+
+ .. versionadded:: 1.11
+
+ A version of :meth:`str.format` for when ``format_string``, ``args``,
+ and/or ``kwargs`` contain lazy objects. The first argument is the string to
+ be formatted. For example::
+
+ from django.utils.text import format_lazy
+ from django.utils.translation import pgettext_lazy
+
+ urlpatterns = [
+ url(format_lazy(r'{person}/(?P<pk>\d+)/$', person=pgettext_lazy('URL', 'person')),
+ PersonDetailView.as_view()),
+ ]
+
+ This example allows translators to translate part of the URL. If "person"
+ is translated to "persona", the regular expression will match
+ ``persona/(?P<pk>\d+)/$``, e.g. ``persona/5/``.
+
.. function:: slugify(allow_unicode=False)
Converts to ASCII if ``allow_unicode`` is ``False`` (default). Converts spaces to
diff --git a/tests/utils_tests/test_text.py b/tests/utils_tests/test_text.py
index df4c055503..1ce993bdb2 100644
--- a/tests/utils_tests/test_text.py
+++ b/tests/utils_tests/test_text.py
@@ -6,7 +6,8 @@ import json
from django.test import SimpleTestCase
from django.utils import six, text
from django.utils.functional import lazystr
-from django.utils.translation import override
+from django.utils.text import format_lazy
+from django.utils.translation import override, ugettext_lazy
IS_WIDE_BUILD = (len('\U0001F4A9') == 1)
@@ -225,3 +226,24 @@ class TestUtilsText(SimpleTestCase):
out = text.compress_sequence(seq)
compressed_length = len(b''.join(out))
self.assertTrue(compressed_length < actual_length)
+
+ def test_format_lazy(self):
+ self.assertEqual('django/test', format_lazy('{}/{}', 'django', lazystr('test')))
+ self.assertEqual('django/test', format_lazy('{0}/{1}', *('django', 'test')))
+ self.assertEqual('django/test', format_lazy('{a}/{b}', **{'a': 'django', 'b': 'test'}))
+ self.assertEqual('django/test', format_lazy('{a[0]}/{a[1]}', a=('django', 'test')))
+
+ t = {}
+ s = format_lazy('{0[a]}-{p[a]}', t, p=t)
+ t['a'] = lazystr('django')
+ self.assertEqual('django-django', s)
+ t['a'] = 'update'
+ self.assertEqual('update-update', s)
+
+ # The format string can be lazy. (string comes from contrib.admin)
+ s = format_lazy(
+ ugettext_lazy("Added {name} \"{object}\"."),
+ name='article', object='My first try',
+ )
+ with override('fr'):
+ self.assertEqual('article «\xa0My first try\xa0» ajouté.', s)