diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index c9fc014cc4..f4c70acd59 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -2,6 +2,7 @@ from django import forms, template from django.conf import settings from django.contrib.admin.filterspecs import FilterSpec from django.contrib.admin.views.decorators import staff_member_required +from django.views.decorators.cache import never_cache from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist, PermissionDenied from django.core.paginator import ObjectPaginator, InvalidPage @@ -394,7 +395,7 @@ def change_stage(request, app_label, model_name, object_id): 'is_popup': request.REQUEST.has_key('_popup'), }) return render_change_form(model, manipulator, c, change=True) -change_stage = staff_member_required(change_stage) +change_stage = staff_member_required(never_cache(change_stage)) def _nest_help(obj, depth, val): current = obj @@ -515,7 +516,7 @@ def delete_stage(request, app_label, model_name, object_id): return render_to_response(["admin/%s/%s/delete_confirmation" % (app_label, opts.object_name.lower() ), "admin/%s/delete_confirmation" % app_label , "admin/delete_confirmation"], extra_context, context_instance=template.RequestContext(request)) -delete_stage = staff_member_required(delete_stage) +delete_stage = staff_member_required(never_cache(delete_stage)) def history(request, app_label, model_name, object_id): model = models.get_model(app_label, model_name) diff --git a/django/utils/cache.py b/django/utils/cache.py index 7c7a41bafa..18f543a16b 100644 --- a/django/utils/cache.py +++ b/django/utils/cache.py @@ -80,6 +80,8 @@ def patch_response_headers(response, cache_timeout=None): if not response.has_header('Expires'): expires = now + datetime.timedelta(0, cache_timeout) response['Expires'] = expires.strftime('%a, %d %b %Y %H:%M:%S GMT') + if cache_timeout < 0: + cache_timeout = 0 # Can't have max-age negative patch_cache_control(response, max_age=cache_timeout) def patch_vary_headers(response, newheaders): diff --git a/django/views/decorators/cache.py b/django/views/decorators/cache.py index f86372cf4e..9413474e1c 100644 --- a/django/views/decorators/cache.py +++ b/django/views/decorators/cache.py @@ -13,8 +13,9 @@ account on caching -- just like the middleware does. import re from django.utils.decorators import decorator_from_middleware -from django.utils.cache import patch_cache_control +from django.utils.cache import patch_cache_control, patch_response_headers from django.middleware.cache import CacheMiddleware +import datetime cache_page = decorator_from_middleware(CacheMiddleware) @@ -31,3 +32,14 @@ def cache_control(**kwargs): return _cache_controller + +def never_cache(view_func): + """ + Decorator that adds headers to a response so that it will + never be cached. + """ + def _wrapped_view_func(request, *args, **kwargs): + response = view_func(request, *args, **kwargs) + patch_response_headers(response, cache_timeout=-1) + return response + return _wrapped_view_func