Ticket #10107: patch.diff

File patch.diff, 5.5 KB (added by matehat, 6 years ago)

New patch for regressiontests, documentation and django.utils.safestring

  • django/utils/safestring.py

     
    44that the producer of the string has already turned characters that should not
    55be interpreted by the HTML engine (e.g. '<') into the appropriate entities.
    66"""
    7 from django.utils.functional import curry, Promise
     7from django.utils.functional import curry, wraps, Promise
    88
    99class EscapeData(object):
    1010    pass
     
    8686
    8787    encode = curry(_proxy_method, method = unicode.encode)
    8888
     89def _safety_decorator(safety_marker, func):
     90  def wrapped(*args, **kwargs):
     91    return safety_marker(func(*args, **kwargs))
     92  return wraps(func)(wrapped)
     93
     94
    8995def mark_safe(s):
    9096    """
    9197    Explicitly mark a string as safe for (HTML) output purposes. The returned
    9298    object can be used everywhere a string or unicode object is appropriate.
    9399
     100    If used on a method as a decorator, mark the returned data as safe.
     101
    94102    Can be called multiple times on a single string.
    95103    """
     104    if callable(s):
     105        return _safety_decorator(mark_safe, s)
    96106    if isinstance(s, SafeData):
    97107        return s
    98108    if isinstance(s, str) or (isinstance(s, Promise) and s._delegate_str):
     
    106116    Explicitly mark a string as requiring HTML escaping upon output. Has no
    107117    effect on SafeData subclasses.
    108118
     119    If used on a method as a decorator, mark the returned data as requiring HTML
     120    escaping.
     121
    109122    Can be called multiple times on a single string (the resulting escaping is
    110123    only applied once).
    111124    """
     125   
     126    if callable(s):
     127        return _safety_decorator(mark_for_escaping, s)
    112128    if isinstance(s, (SafeData, EscapeData)):
    113129        return s
    114130    if isinstance(s, str) or (isinstance(s, Promise) and s._delegate_str):
  • docs/topics/templates.txt

     
    486486    This will be escaped: &lt;b&gt;
    487487    This will not be escaped: <b>
    488488
     489For methods
     490~~~~~~~~~~~
     491
     492To control whether the data returned by a method is escaped or not when outputted
     493in a template, use
     494:func:`django.utils.safestring.mark_safe`
     495and
     496:func:`django.utils.safestring.mark_for_escaping`.
     497Here is an example ::
     498
     499    def nice_html_content():
     500        # Build up some html content
     501        return mark_safe(content)
     502
     503The :func:`mark_safe` and :func:`mark_for_escaping` methods can also be used as decorators
     504on methods to mark whatever data is returned by it as being safe or not. This can come in handy
     505when a method has many different return points in a quite complicated schema.
     506
    489507For template blocks
    490508~~~~~~~~~~~~~~~~~~~
    491509
  • tests/regressiontests/decorators/tests.py

     
    33
    44from django.http import HttpResponse
    55from django.utils.functional import allow_lazy, lazy, memoize
     6from django.utils.safestring import mark_safe, mark_for_escaping
    67from django.views.decorators.http import require_http_methods, require_GET, require_POST
    78from django.views.decorators.vary import vary_on_headers, vary_on_cookie
    89from django.views.decorators.cache import cache_page, never_cache, cache_control
     
    4243fully_decorated = allow_lazy(fully_decorated)
    4344fully_decorated = lazy(fully_decorated)
    4445
     46# django.utils.safestring
     47fully_decorated = mark_safe(fully_decorated)
     48fully_decorated = mark_for_escaping(fully_decorated)
     49
    4550class DecoratorsTest(TestCase):
    4651
    4752    def test_attributes(self):
     
    5661        self.assertEquals(fully_decorated.__doc__, 'Expected __doc__')
    5762        self.assertEquals(fully_decorated.__dict__['anything'], 'Expected __dict__')
    5863
     64    def test_escaping(self):
     65        """
     66        Tests that safety markers from django.utils.safestring
     67        return the proper str or unicode subclass for use in templates.
     68       
     69        Tests are done by comparing directly a sample rendered Template instance
     70        with the unicode content it should contain.
     71        """
     72        from django.template import Template, Context
     73        template = Template("{{ data }}")
     74
     75        rendered = { 'safe': u'<html><body>dummy</body></html>',
     76          'escaped': u'&lt;html&gt;&lt;body&gt;dummy&lt;/body&gt;&lt;/html&gt;' }
     77        def clean_unicode_provider():
     78            return u'<html><body>dummy</body></html>'
     79
     80        def clean_string_provider():
     81            return '<html><body>dummy</body></html>'
     82
     83        escaped_unicode = mark_for_escaping(clean_unicode_provider)()
     84        safe_unicode = mark_safe(clean_unicode_provider)()
     85        escaped_str = mark_for_escaping(clean_string_provider)()
     86        safe_str = mark_safe(clean_string_provider)()
     87
     88        self.assertEquals(template.render(Context({'data': escaped_unicode})),
     89            rendered['escaped'])
     90        self.assertEquals(template.render(Context({'data': safe_unicode})),
     91            rendered['safe'])
     92        self.assertEquals(template.render(Context({'data': escaped_str})),
     93            rendered['escaped'])
     94        self.assertEquals(template.render(Context({'data': safe_str})),
     95            rendered['safe'])
     96
    5997    def test_user_passes_test_composition(self):
    6098        """
    6199        Test that the user_passes_test decorator can be applied multiple times
Back to Top