diff --git a/django/template/context.py b/django/template/context.py index 04d0e2f5f4..361f3503ca 100644 --- a/django/template/context.py +++ b/django/template/context.py @@ -1,6 +1,9 @@ +import warnings from contextlib import contextmanager from copy import copy +from django.utils.deprecation import RemovedInDjango20Warning + # Hard-coded processor for easier use of CSRF protection. _builtin_context_processors = ('django.template.context_processors.csrf',) @@ -76,14 +79,18 @@ class BaseContext(object): del self.dicts[-1][key] def has_key(self, key): + warnings.warn( + "%s.has_key() is deprecated in favor of the 'in' operator." % self.__class__.__name__, + RemovedInDjango20Warning + ) + return key in self + + def __contains__(self, key): for d in self.dicts: if key in d: return True return False - def __contains__(self, key): - return self.has_key(key) - def get(self, key, otherwise=None): for d in reversed(self.dicts): if key in d: @@ -184,7 +191,7 @@ class RenderContext(BaseContext): for d in self.dicts[-1]: yield d - def has_key(self, key): + def __contains__(self, key): return key in self.dicts[-1] def get(self, key, otherwise=None): diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index 13d9305658..d1f877aa06 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -133,6 +133,8 @@ details on these changes. * The model ``CommaSeparatedIntegerField`` will be removed. A stub field will remain for compatibility with historical migrations. +* Support for the template ``Context.has_key()`` method will be removed. + .. _deprecation-removed-in-1.10: 1.10 diff --git a/docs/releases/1.10.txt b/docs/releases/1.10.txt index 658a3646bd..fc7b03d2a7 100644 --- a/docs/releases/1.10.txt +++ b/docs/releases/1.10.txt @@ -678,6 +678,8 @@ Miscellaneous * Importing from the ``django.core.urlresolvers`` module is deprecated in favor of its new location, :mod:`django.urls`. +* The template ``Context.has_key()`` method is deprecated in favor of ``in``. + .. _removed-features-1.10: Features removed in 1.10 diff --git a/tests/template_tests/test_context.py b/tests/template_tests/test_context.py index 87b2016aa5..2fa7715d27 100644 --- a/tests/template_tests/test_context.py +++ b/tests/template_tests/test_context.py @@ -1,11 +1,13 @@ # -*- coding: utf-8 -*- +import warnings from django.http import HttpRequest from django.template import ( Context, Engine, RequestContext, Template, Variable, VariableDoesNotExist, ) from django.template.context import RenderContext -from django.test import RequestFactory, SimpleTestCase +from django.test import RequestFactory, SimpleTestCase, ignore_warnings +from django.utils.deprecation import RemovedInDjango20Warning class ContextTests(SimpleTestCase): @@ -182,6 +184,26 @@ class ContextTests(SimpleTestCase): """ RequestContext(HttpRequest()).new().new() + @ignore_warnings(category=RemovedInDjango20Warning) + def test_has_key(self): + a = Context({'a': 1}) + b = RequestContext(HttpRequest(), {'a': 1}) + msg = "Context.has_key() is deprecated in favor of the 'in' operator." + msg2 = "RequestContext.has_key() is deprecated in favor of the 'in' operator." + + with warnings.catch_warnings(record=True) as warns: + warnings.simplefilter('always') + self.assertEqual(a.has_key('a'), True) + self.assertEqual(a.has_key('b'), False) + self.assertEqual(b.has_key('a'), True) + self.assertEqual(b.has_key('b'), False) + + self.assertEqual(len(warns), 4) + self.assertEqual(str(warns[0].message), msg) + self.assertEqual(str(warns[1].message), msg) + self.assertEqual(str(warns[2].message), msg2) + self.assertEqual(str(warns[3].message), msg2) + class RequestContextTests(SimpleTestCase):