2016-08-15 2 views
1

Может ли кто-нибудь объяснить, почему переопределение get_queryset и ссылка на запрос через self полностью кэширует страницу? Мне нужно подождать 5 минут и более до того, как будут сделаны обновления на дисплее базы данных.Переопределение get_queryset приводит к кешированию головной боли в ListView, где данные остаются устаревшими

Я пытаюсь сохранить временное значение для каждого объекта и передать его в шаблон.

У меня все работает отлично и денди в примере 3, но на самом деле я не понимаю, что я сделал, чтобы заставить его работать, поэтому любое понимание было бы замечательным!

Пример 1: Тайники в течение нескольких минут, но r.css = 'а' работают нормально

class AppointmentListView(ListView): 
    qs = Appointment.objects.prefetch_related('client', 'patients') 

    def get_queryset(self): 
     for r in self.qs: 
      r.css = 'abc' #<-passes temp value to template ok 
     return self.qs 

Пример 2: Нет проблемы кэширования, но r.css = 'а' теперь не работает

Если я не включаю метод и просто вызываю запрос автоматически, не происходит немедленного отображения кеширования и базы данных, но мои временные данные не достигают шаблона. класса AppointmentListView (ListView):

queryset = Appointment.objects.prefetch_related('client','patients') 

    for r in queryset: 
     r.css = 'abc' #<- NOT passed to template 

Пример 3: Нет проблемы кэширования и r.css = «а» работает отлично

Наконец, если я ставлю все в методе, все работает отлично - Темп данные достигает шаблона, и нет кеширования.

ответ

1

Поведение, которое вы видите, это то, как Python оценивает ваш код. Ниже приведен упрощенный пример, который объясняет, что вы видите.

import random 

class Example1(object): 
    roll = random.randint(1, 6) # this is evaluated immediately! 
    def get_roll(self): 
     return self.roll 

ex1 = Example1() 

# the call below always returns the same number! 
# (until Python re-interprets the class) 
ex1.get_roll() 

Если вы набираете код, указанной выше в интерпретатор Python, вы заметите, что ex1.get_roll() всегда возвращают тот же номер!

Example1.roll известен как класс или статическая переменная. Они оцениваются только один раз, когда класс определен.

class Example2(object): 
    def get_number(self): 
     roll = random.randint(1,6) 
     return roll 

В Example2, новое случайное число генерируется каждый раз, когда get_roll метод вызывается.

Для примеров, перечисленных в вашем вопросе:

Пример 1

qs является переменной класса, и, таким образом, только получает оценку один раз (именно поэтому вы видите «кэширование» поведение). Последующие вызовы get_queryset возвращают ту же переменную qs, которая была первоначально оценена.

Пример 2

Вы не переопределяют get_queryset, что означает, используется ListView.get_queryset реализации.

Django's ListView.get_queryset копирует queryset перед его оценкой - поэтому вы не видите «кеширование». Однако, поскольку набор запросов копируется, эффекты из цикла for исключаются.

Пример 3

Это, как правило, правильный способ написания кода. Вы должны написать свои методы следующим образом, если вы не хотите видеть поведение «кэширования».

+0

Отличный ответ, спасибо Дерек. –

Смежные вопросы