Ответ
Технически да, но это плохая практика для кэширования данных между запросами из-за особенностей жизненного цикла экземпляров View в Django. Однако это приемлемый способ избежать повторных вычислений в рамках одного запроса.
Проблема: Состояние View между запросами
Django может переиспользовать один и тот же экземпляр View для обработки нескольких запросов от разных пользователей. Если вы сохраните данные в атрибуте экземпляра (self.my_data = ...), эти данные могут "протечь" в следующий запрос, что приведет к показу неверной или чужой информации.
Анти-паттерн (не делайте так для межзапросного кэша):
class LeakyView(View):
_cached_data = None # Атрибут будет жить дольше одного запроса
def get(self, request):
if self._cached_data is None:
# Тяжелая операция, выполняется только один раз для экземпляра
self._cached_data = heavy_database_query()
return HttpResponse(self._cached_data)
Правильный подход: Кэширование в рамках одного запроса
Если вам нужно вычислить значение один раз и использовать его в нескольких методах View в течение обработки одного запроса (например, в get_context_data и get), используйте декоратор @cached_property.
from django.utils.functional import cached_property
from django.views.generic import TemplateView
class MyView(TemplateView):
template_name = "my_template.html"
@cached_property
def complex_data(self):
# Эта тяжелая операция выполнится только один раз за запрос
print("Выполняется дорогой запрос...")
return list(MyModel.objects.filter(is_active=True))
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['items'] = self.complex_data # Первый вызов
return context
def get(self, request, *args, **kwargs):
# ... какая-то логика
print(f"Количество элементов: {len(self.complex_data)}") # Второй вызов, но запрос не повторится
return super().get(request, *args, **kwargs)
Лучшее решение: Django Cache Framework
Для кэширования данных между запросами всегда используйте встроенный фреймворк кэширования Django. Он безопасен и предоставляет контроль над временем жизни кэша.
from django.core.cache import cache
def get_data_view(request):
data = cache.get('my_unique_cache_key')
if data is None:
data = heavy_database_query()
cache.set('my_unique_cache_key', data, timeout=300) # Кэш на 5 минут
return HttpResponse(data)