Вопрос
В Django, как создать единую кешированную версию страницы (то же самое для всех пользователей), которая доступна только для аутентифицированных пользователей?
Настройка
Страницы, которые я хочу кэшировать, доступны только для аутентифицированных пользователей (они используют @login_required
в представлении). Эти страницы одинаковы для всех пользователей, прошедших проверку подлинности (например, нет необходимости настраивать vary_on_headers
на основе уникальных пользователей).
Однако я не хочу, чтобы эти кэшированные страницы были видимыми для пользователей, не прошедших проверку подлинности.
То, что я пробовал до сих пор
- Кэш уровня страницы (отображает страницы, предназначенные для входа в систему пользователям без регистрации)
- Посмотрел на использование
vary_on_headers
, но мне не нужны отдельные кешированные страницы для каждого пользователя. - Я проверил кэширование фрагмента шаблона, но, если я не смущен, это не удовлетворит мои потребности.
- Существенный поиск (кажется, что все хотят сделать обратное)
Спасибо!
Пример просмотра
@login_required
@cache_page(60 * 60)
def index(request):
'''Display the home page'''
return render(request, 'index.html')
settings.py(соответствующая часть)
# Add the below for memcache
MIDDLEWARE_CLASSES += (
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
)
# Enable memcache
# https://devcenter.heroku.com/articles/memcache#using_memcache_from_python
CACHES = {
'default': {
'BACKEND': 'django_pylibmc.memcached.PyLibMCCache'
}
}
Решение
Основываясь на ответе @Tisho, я решил эту проблему
- Создание файла
decorators.py
в моем приложении - Добавление к нему приведенного ниже кода
- Импорт функции в
views.py
- Применение его в качестве декоратора к представлениям, которые я хотел кэшировать только для зарегистрированных пользователей
decorators.py
from functools import wraps
from django.views.decorators.cache import cache_page
from django.utils.decorators import available_attrs
def cache_on_auth(timeout):
def decorator(view_func):
@wraps(view_func, assigned=available_attrs(view_func))
def _wrapped_view(request, *args, **kwargs):
if request.user.is_authenticated():
return cache_page(timeout)(view_func)(request, *args, **kwargs)
else:
return view_func(request, *args, **kwargs)
return _wrapped_view
return decorator
Для зарегистрированных пользователей он будет кэшировать страницу (или обслуживать их кэшированную страницу) для не зарегистрированных пользователей, она просто даст им обычный вид, который был украшен @login_required
и потребует от них входа в систему.