Browse Source

Fixed #21741 -- Fixed render_to_string to stop pushing empty dictionaries to its Context

Thanks to kezabelle for the report and original patch
and to numerodix for his improved patch.
Baptiste Mispelon 11 năm trước cách đây
mục cha
commit
7e1376c2b0

+ 2 - 1
django/template/loader.py

@@ -164,13 +164,14 @@ def render_to_string(template_name, dictionary=None, context_instance=None,
     get_template, or it may be a tuple to use select_template to find one of
     the templates in the list. Returns a string.
     """
-    dictionary = dictionary or {}
     if isinstance(template_name, (list, tuple)):
         t = select_template(template_name, dirs)
     else:
         t = get_template(template_name, dirs)
     if not context_instance:
         return t.render(Context(dictionary))
+    if not dictionary:
+        return t.render(context_instance)
     # Add the dictionary to the context stack, ensuring it gets removed again
     # to keep the context_instance in the same state it started in.
     with context_instance.push(dictionary):

+ 2 - 0
tests/template_tests/templates/test_context_stack.html

@@ -0,0 +1,2 @@
+{% load custom %}
+{% context_stack_length %}

+ 5 - 0
tests/template_tests/templatetags/custom.py

@@ -22,6 +22,11 @@ def noop(value, param=None):
     return value
 
 
+@register.simple_tag(takes_context=True)
+def context_stack_length(context):
+    return len(context.dicts)
+
+
 @register.simple_tag
 def no_params():
     """Expected no_params __doc__"""

+ 12 - 0
tests/template_tests/test_loaders.py

@@ -171,6 +171,18 @@ class RenderToStringTest(TestCase):
             'No template names provided$',
             loader.select_template, [])
 
+    def test_no_empty_dict_pushed_to_stack(self):
+        """
+        No empty dict should be pushed to the context stack when render_to_string
+        is called without any argument (#21741).
+        """
+
+        # The stack should have a length of 1, corresponding to the builtins
+        self.assertEqual('1',
+            loader.render_to_string('test_context_stack.html').strip())
+        self.assertEqual('1',
+            loader.render_to_string('test_context_stack.html', context_instance=Context()).strip())
+
 
 class TemplateDirsOverrideTest(unittest.TestCase):