Куда мне положить мои Django промежуточные программы для кеша? - PullRequest
0 голосов
/ 28 января 2020

Я попытался добавить кеширование в свой Django проект, поэтому я добавил промежуточное программное обеспечение для кеша, как указано (для того, что я понял) в официальных документах, и получил это:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.middleware.cache.UpdateCacheMiddleware',
    'debug_toolbar.middleware.DebugToolbarMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.cache.FetchFromCacheMiddleware',
]

Но это нарушает мою систему аутентификации: на других страницах я получаю разные наборы запросов для разных уровней аутентификации, но если я добавлю эти промежуточные программы, одна и та же страница будет показана всем пользователям. Как я могу реализовать кеширование в своем проекте и при этом иметь возможность предоставлять страницы различным наборам запросов для разных пользователей?

Вот моя функция из views.py:

class ProgettoListView(generic.ListView, LoginRequiredMixin):
    model = Progetto
    template_name = 'main/list/progetto_list.html'

    def get_context_data(self, **kwargs):
        context = super(ProgettoListView, self).get_context_data(**kwargs)
        context['ore'] = []
        for progetto in Progetto.objects.all():
            ore_lavoro = Task.objects.filter(progetto=progetto).aggregate(sum_all=Sum('durata')).get('sum_all')
            if ore_lavoro is None:
                ore_lavoro = datetime.timedelta(0)
            context['ore'].append({'nome': progetto.nome, 'ore_lavorate': ore_lavoro,
                                   'percentuale': int(ore_lavoro / progetto.tempo_stimato * 100)})
        return context

    def get_queryset(self):
        if self.request.user.is_amm:
            return self.model.objects.all()
        return self.model.objects.filter(auts=self.request.user)

, где is_amm - просто логическое поле, auts - список пользователей.

Здесь это строка из urls.py:

    path('pm/lista/progetti', login_required(views.ProgettoListView.as_view()), name='lista-progetti'),

Проблема, с которой я сталкиваюсь, заключается в том, что пользователь с установленным значением true для is_amm должен видеть все проекты в базе данных при посещении страницы списка, но этого не происходит. Например, если я сделаю новый проект с этим пользователем, он не сможет увидеть его в списке, хотя сможет получить к нему доступ через прямой URL.

1 Ответ

0 голосов
/ 28 января 2020

Похоже, проблема, с которой вы сталкиваетесь, заключается в том, что представления кэшируются с неправильными разрешениями. Я предполагаю, что вы добавили декоратор cache_page к просмотрам. Проблема этого подхода заключается в том, что он собирается кэшировать ответ на любой запрос к указанному URL c. Чтобы разрешить URL иметь несколько кэшированных ответов, есть как минимум две опции.

  1. Создайте новый декоратор, аналогичный (или оберните) cache_page, чтобы декоратор проверял разрешения пользователя, а затем извлекал соответствующий кэшированный ответ.
  2. Не используйте cache_page и управляйте кэшированием вручную с помощью низкого уровня API .

Лично я бы выбрал для # 2 это будет немного яснее, но я думаю, что # 1 может быть более кратким.

...