Django ListView - получение последнего связанного объекта и предотвращение кэширования представления или запроса к базе данных в Django
У меня есть модель Campaign
и модель CampaignStatus
, внешним ключом которой является модель Campaign
. Когда кампания редактируется или создается, она проходит через несколько статусов и имеет объект CampaignStatus
, связанный с каждым изменением статуса.
Используя CBVs Django, у меня есть представление списка, которое показывает Кампании пользователя, и я хочу передать шаблону самый последний статус в контексте.
Django, похоже, кэширует статус, и я не знаю, как это предотвратить. (Возможно, уместно: представление кампании в Django admin также имеет ту же проблему с кэшированием - я определил метод для получения самого последнего статуса. Представление списка в Django admin CampaignStatus
ведет себя как ожидалось, всегда показывая новые статусы, как только они создаются.)
Я хотел бы, чтобы кэш составлял 5 секунд, но он составляет около 3 минут. Как я могу это изменить?
Фрагмент кода из общего ListView, который мы используем:
@method_decorator(cache_page(5), name="dispatch") # single arg is seconds
class CampaignsListView(LoginRequiredMixin, ListView):
model = Campaign
paginate_by = 100
template_name = "writing/user_campaigns.html"
context_object_name = "user_campaigns"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
for i, _ in enumerate(context.get("user_campaigns")):
campaign = context["user_campaigns"][i]
campaign_status = CampaignStatus.objects.filter(campaign=campaign).latest("-status")
context["user_campaigns"][i].status = campaign_status.get_status_display()
return context
def get_queryset(self):
return Campaign.objects.filter(user=self.request.user).order_by("-modified")
#... some other methods too
Я думаю, что вы можете найти лучшее решение, но вы можете написать сигнал post_save, отбрасывающий аннулирование кэша. Что-то вроде этого:
from django.core.cache import cache
def invalidate_cache_page(
view: str,
path_params: Optional[Dict[str, Any]] = None,
key_prefix: str = '',
partial: bool = True
) -> None:
"""
Invalidate page cache.
"""
cache_key = generate_cache_key(view, path_params, {}, key_prefix, partial)
if hasattr(cache, 'keys'):
keys = cache.keys(cache_key) or []
cache.delete_many(keys)
else:
cache.delete(cache_key)
generate_cache_key ваша собственная функция для генерации