mirror of https://github.com/django/django.git
Fixed #10107 -- Allowed using mark_safe() as a decorator.
Thanks ArcTanSusan for the initial patch.
This commit is contained in:
parent
5e3f4c2e53
commit
be729b6120
|
@ -8,7 +8,7 @@ import warnings
|
|||
|
||||
from django.utils import six
|
||||
from django.utils.deprecation import RemovedInDjango20Warning
|
||||
from django.utils.functional import Promise, curry
|
||||
from django.utils.functional import Promise, curry, wraps
|
||||
|
||||
|
||||
class EscapeData(object):
|
||||
|
@ -117,11 +117,20 @@ else:
|
|||
SafeUnicode = SafeText
|
||||
|
||||
|
||||
def _safety_decorator(safety_marker, func):
|
||||
@wraps(func)
|
||||
def wrapped(*args, **kwargs):
|
||||
return safety_marker(func(*args, **kwargs))
|
||||
return wrapped
|
||||
|
||||
|
||||
def mark_safe(s):
|
||||
"""
|
||||
Explicitly mark a string as safe for (HTML) output purposes. The returned
|
||||
object can be used everywhere a string or unicode object is appropriate.
|
||||
|
||||
If used on a method as a decorator, mark the returned data as safe.
|
||||
|
||||
Can be called multiple times on a single string.
|
||||
"""
|
||||
if hasattr(s, '__html__'):
|
||||
|
@ -130,6 +139,8 @@ def mark_safe(s):
|
|||
return SafeBytes(s)
|
||||
if isinstance(s, (six.text_type, Promise)):
|
||||
return SafeText(s)
|
||||
if callable(s):
|
||||
return _safety_decorator(mark_safe, s)
|
||||
return SafeString(str(s))
|
||||
|
||||
|
||||
|
|
|
@ -832,6 +832,8 @@ appropriate entities.
|
|||
|
||||
Can be called multiple times on a single string.
|
||||
|
||||
Can also be used as a decorator.
|
||||
|
||||
For building up fragments of HTML, you should normally be using
|
||||
:func:`django.utils.html.format_html` instead.
|
||||
|
||||
|
@ -846,6 +848,10 @@ appropriate entities.
|
|||
>>> type(mystr)
|
||||
<type 'str'>
|
||||
|
||||
.. versionchanged:: 1.11
|
||||
|
||||
Added support for decorator usage.
|
||||
|
||||
.. function:: mark_for_escaping(s)
|
||||
|
||||
.. deprecated:: 1.10
|
||||
|
|
|
@ -202,7 +202,7 @@ Signals
|
|||
Templates
|
||||
~~~~~~~~~
|
||||
|
||||
* ...
|
||||
* :meth:`~django.utils.safestring.mark_safe` can now be used as a decorator.
|
||||
|
||||
Tests
|
||||
~~~~~
|
||||
|
|
|
@ -13,6 +13,7 @@ from django.utils.decorators import method_decorator
|
|||
from django.utils.deprecation import RemovedInDjango20Warning
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.functional import allow_lazy, keep_lazy, keep_lazy_text, lazy
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import ugettext_lazy
|
||||
from django.views.decorators.cache import (
|
||||
cache_control, cache_page, never_cache,
|
||||
|
@ -74,6 +75,9 @@ full_decorator = compose(
|
|||
keep_lazy(HttpResponse),
|
||||
keep_lazy_text,
|
||||
lazy,
|
||||
|
||||
# django.utils.safestring
|
||||
mark_safe,
|
||||
)
|
||||
|
||||
fully_decorated = full_decorator(fully_decorated)
|
||||
|
|
|
@ -109,3 +109,33 @@ class SafeStringTest(SimpleTestCase):
|
|||
s = text.slugify(lazystr('a'))
|
||||
s += mark_safe('&b')
|
||||
self.assertRenderEqual('{{ s }}', 'a&b', s=s)
|
||||
|
||||
def test_mark_safe_as_decorator(self):
|
||||
"""
|
||||
mark_safe used as a decorator leaves the result of a function
|
||||
unchanged.
|
||||
"""
|
||||
def clean_string_provider():
|
||||
return '<html><body>dummy</body></html>'
|
||||
|
||||
self.assertEqual(mark_safe(clean_string_provider)(), clean_string_provider())
|
||||
|
||||
def test_mark_safe_decorator_does_not_affect_dunder_html(self):
|
||||
"""
|
||||
mark_safe doesn't affect a callable that has an __html__() method.
|
||||
"""
|
||||
class SafeStringContainer:
|
||||
def __html__(self):
|
||||
return '<html></html>'
|
||||
|
||||
self.assertIs(mark_safe(SafeStringContainer), SafeStringContainer)
|
||||
|
||||
def test_mark_safe_decorator_does_not_affect_promises(self):
|
||||
"""
|
||||
mark_safe doesn't affect lazy strings (Promise objects).
|
||||
"""
|
||||
def html_str():
|
||||
return '<html></html>'
|
||||
|
||||
lazy_str = lazy(html_str, str)()
|
||||
self.assertEqual(mark_safe(lazy_str), html_str())
|
||||
|
|
Loading…
Reference in New Issue