Избегайте обращений к базе данных при запросах только GET (с использованием django-cachalot)

Django==4.0.6

django-cachalot==2.5.1

Модели:

from django.db import models
from django.urls import reverse
class Poll(models.Model):
    name = models.CharField(max_length=200)
    def get_absolute_url(self):
        return reverse("poll", kwargs={'pk': self.id})
    def __str__(self):
        return self.name
class Question(models.Model):
    poll = models.ForeignKey(Poll, on_delete=models.CASCADE)
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    def get_absolute_url(self):
        return reverse("choice", kwargs={'pk': self.id})
    def __str__(self):
        return self.question_text
class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
    def __str__(self):
        return self.choice_text

Templatetags

from django import template
from django.utils.safestring import mark_safe

from polls.models import Question

register = template.Library()


@register.simple_tag(takes_context=True)
def question(context, id):
    question = Question.objects.get(pk=id)

    choices = question.choice_set.all()
    html = "<p>" + question.question_text +"</p>"
    html += "<p>Answers</p>"

    for choice in choices:
        html += "<p>" + choice.choice_text + ": " + str(choice.votes) + "</p>"

    return mark_safe(html)

cache_project/cache/polls/templates/polls/poll_detail.html

{% extends 'polls/base.html' %}
{% load polls %}


{% block content %}
<p>Poll: {{ object.name }}</p>
<p>Question 1: {% question id=1%}</p>

{% endblock %}

Admin:

from django.contrib import admin
from .models import General
from django.apps import apps


@admin.action(description='Warm cache up')
def warm_up(modeladmin, request, queryset):
    MODELS_AND_APPS = {
        "Poll": "polls",
        "Question": "polls",
        "Choice": "polls",
    }

    for model_name in MODELS_AND_APPS:
        current_model = apps.get_model(app_label=MODELS_AND_APPS[model_name], model_name=model_name)
        all_instances = current_model.objects.all()
        list(all_instances)  # The very warming the cache up.


class GeneralAdmin(admin.ModelAdmin):
    actions = [warm_up]


admin.site.register(General, GeneralAdmin)

Мне не нравится, что база данных попадает в кэш каждый раз, когда поступает GET-запрос. Поэтому я хотел бы разогреть кэш.

Я использую django-cachalot.

  1. Я очищаю кэш. Вы видите, что кэш очищен. enter image description here

  2. Я прогреваю кэш (используя мое админское действие warm_up). Видно, что в кашалоте что-то появилось. enter image description here

  3. Есть некоторые основания полагать, что попадания в базу данных больше не произойдет. Я посылаю запрос к представлению, показывающему список опросов. Попадания в базу данных нет. enter image description here Сессия не учитывается.

  4. Но когда я посылаю запрос к детальному представлению, попадания в базу данных происходят.

enter image description here

Помогите, пожалуйста, разобраться в причине попадания в базу данных. И, самое главное, как заранее прогреть кэш, чтобы не было попаданий?

Вернуться на верх