diff --git a/django/template/base.py b/django/template/base.py index 364b428070..26f8111f1e 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -5,7 +5,7 @@ from functools import partial from inspect import getargspec from django.conf import settings -from django.template.context import (Context, RequestContext, +from django.template.context import (BaseContext, Context, RequestContext, ContextPopException) from django.utils.importlib import import_module from django.utils.itercompat import is_iterable @@ -765,6 +765,9 @@ class Variable(object): current = current[bit] except (TypeError, AttributeError, KeyError, ValueError): try: # attribute lookup + # Don't return class attributes if the class is the context: + if isinstance(current, BaseContext) and getattr(type(current), bit): + raise AttributeError current = getattr(current, bit) except (TypeError, AttributeError): try: # list-index lookup diff --git a/tests/template_tests/test_context.py b/tests/template_tests/test_context.py index 05c1dd57b9..778f4051e8 100644 --- a/tests/template_tests/test_context.py +++ b/tests/template_tests/test_context.py @@ -1,5 +1,5 @@ # coding: utf-8 -from django.template import Context +from django.template import Context, Variable, VariableDoesNotExist from django.utils.unittest import TestCase @@ -14,3 +14,12 @@ class ContextTests(TestCase): self.assertEqual(c.pop(), {"a": 2}) self.assertEqual(c["a"], 1) self.assertEqual(c.get("foo", 42), 42) + + def test_resolve_on_context_method(self): + # Regression test for #17778 + empty_context = Context() + self.assertRaises(VariableDoesNotExist, + Variable('no_such_variable').resolve, empty_context) + self.assertRaises(VariableDoesNotExist, + Variable('new').resolve, empty_context) + self.assertEqual(Variable('new').resolve(Context({'new': 'foo'})), 'foo')