diff --git a/django/views/decorators/cache.py b/django/views/decorators/cache.py index d96d71651e..a39cc54e33 100644 --- a/django/views/decorators/cache.py +++ b/django/views/decorators/cache.py @@ -39,8 +39,16 @@ def cache_page(*args, **kwargs): cache_alias = kwargs.pop('cache', None) key_prefix = kwargs.pop('key_prefix', None) assert not kwargs, "The only keyword arguments are cache and key_prefix" + def warn(): + import warnings + warnings.warn('The cache_page decorator must be called like: ' + 'cache_page(timeout, [cache=cache name], [key_prefix=key prefix]). ' + 'All other ways are deprecated.', + PendingDeprecationWarning) + if len(args) > 1: assert len(args) == 2, "cache_page accepts at most 2 arguments" + warn() if callable(args[0]): return decorator_from_middleware_with_args(CacheMiddleware)(cache_timeout=args[1], cache_alias=cache_alias, key_prefix=key_prefix)(args[0]) elif callable(args[1]): @@ -49,10 +57,13 @@ def cache_page(*args, **kwargs): assert False, "cache_page must be passed a view function if called with two arguments" elif len(args) == 1: if callable(args[0]): + warn() return decorator_from_middleware_with_args(CacheMiddleware)(cache_alias=cache_alias, key_prefix=key_prefix)(args[0]) else: + # The One True Way return decorator_from_middleware_with_args(CacheMiddleware)(cache_timeout=args[0], cache_alias=cache_alias, key_prefix=key_prefix) else: + warn() return decorator_from_middleware_with_args(CacheMiddleware)(cache_alias=cache_alias, key_prefix=key_prefix) diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt index 4d81cb7ba3..131f813f83 100644 --- a/docs/internals/deprecation.txt +++ b/docs/internals/deprecation.txt @@ -207,6 +207,9 @@ their deprecation, as per the :ref:`Django deprecation policy refactored to use class based views with pluggable backends in 1.4. The previous implementation will be deprecated. + * Legacy ways of calling + :func:`~django.views.decorators.cache.cache_page` will be removed. + * 2.0 * ``django.views.defaults.shortcut()``. This function has been moved to ``django.contrib.contenttypes.views.shortcut()`` as part of the diff --git a/docs/releases/1.4.txt b/docs/releases/1.4.txt index bddb15cd3e..83ebaa738b 100644 --- a/docs/releases/1.4.txt +++ b/docs/releases/1.4.txt @@ -8,10 +8,14 @@ up-to-date information for those who are following trunk. Django 1.4 includes various `new features`_ and some minor `backwards incompatible changes`_. There are also some features that have been dropped, -which are detailed in :doc:`our deprecation plan `. +which are detailed in :doc:`our deprecation plan `, and +we've `begun the deprecation process for some features`_. + + .. _new features: `What's new in Django 1.4`_ .. _backwards incompatible changes: backwards-incompatible-changes-1.4_ +.. _begun the deprecation process for some features: deprecated-features-1.4_ What's new in Django 1.4 ======================== @@ -283,4 +287,16 @@ If you using PUT or DELETE methods in AJAX applications, please see the This was an alias to ``django.template.loader`` since 2005, it has been removed without emitting a warning due to the length of the deprecation. If your code -still referenced this please use ``django.template.loader`` instead. \ No newline at end of file +still referenced this please use ``django.template.loader`` instead. + +.. _deprecated-features-1.4: + +Features deprecated in 1.4 +========================== + +Old styles of calling ``cache_page`` decorator +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Some legacy ways of calling :func:`~django.views.decorators.cache.cache_page` +have been deprecated, please see the docs for the correct way to use this +decorator. diff --git a/docs/topics/cache.txt b/docs/topics/cache.txt index 0dbe8446b0..839e03d1e3 100644 --- a/docs/topics/cache.txt +++ b/docs/topics/cache.txt @@ -494,7 +494,7 @@ __ `Controlling cache: Using other headers`_ The per-view cache ================== -.. function ``django.views.decorators.cache.cache_page`` +.. function:: django.views.decorators.cache.cache_page A more granular way to use the caching framework is by caching the output of individual views. ``django.views.decorators.cache`` defines a ``cache_page`` @@ -571,7 +571,7 @@ Here's the same thing, with ``my_view`` wrapped in ``cache_page``:: from django.views.decorators.cache import cache_page urlpatterns = ('', - (r'^foo/(\d{1,2})/$', cache_page(my_view, 60 * 15)), + (r'^foo/(\d{1,2})/$', cache_page(60 * 15)(my_view)), ) If you take this approach, don't forget to import ``cache_page`` within your diff --git a/tests/regressiontests/decorators/tests.py b/tests/regressiontests/decorators/tests.py index 8a03980f88..f1d1c10975 100644 --- a/tests/regressiontests/decorators/tests.py +++ b/tests/regressiontests/decorators/tests.py @@ -1,8 +1,10 @@ from functools import wraps +import warnings from django.contrib.auth.decorators import login_required, permission_required, user_passes_test from django.contrib.admin.views.decorators import staff_member_required from django.http import HttpResponse, HttpRequest, HttpResponseNotAllowed +from django.test.utils import get_warnings_state, restore_warnings_state from django.utils.decorators import method_decorator from django.utils.functional import allow_lazy, lazy, memoize from django.utils.unittest import TestCase @@ -65,6 +67,14 @@ fully_decorated = full_decorator(fully_decorated) class DecoratorsTest(TestCase): + def setUp(self): + self.warning_state = get_warnings_state() + warnings.filterwarnings('ignore', category=PendingDeprecationWarning, + module='django.views.decorators.cache') + + def tearDown(self): + restore_warnings_state(self.warning_state) + def test_attributes(self): """ Tests that django decorators set certain attributes of the wrapped