有人可以解释为什么重写get_queryset
并通过self
引用查询集完全缓存页面吗?我需要等待5分钟或更长时间才能对数据库显示进行更新。
我正在尝试将临时值保存到每个对象,并将其传递给模板。
在示例3中,我的所有工作都很好,但还不太了解如何使它工作,所以任何见解都很棒!
示例1:缓存了几分钟,但r.css ='abc'正常工作
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 ='abc'现在不起作用
如果我不包括方法,而只是自动调用queryset,则不会进行缓存,也不会立即显示数据库更新,但是我的临时数据无法到达模板。
类AppointmentListView(ListView):
queryset = Appointment.objects.prefetch_related('client','patients')
for r in queryset:
r.css = 'abc' #<- NOT passed to template
示例3:没有缓存问题,并且r.css ='abc'正常工作
最后,如果我将所有内容都放入方法中,则一切正常-临时数据到达模板,并且没有缓存。
class AppointmentListView(ListView):
def get_queryset(self):
qs = Appointment.objects.prefetch_related('client','patients')
for r in qs:
r.css = 'abc' #<-passes to template ok
return qs
最佳答案
您看到的行为是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的
ListView.get_queryset
在评估之前复制queryset
-这就是为什么您看不到“缓存”的原因。但是,由于复制了查询集,因此丢弃了来自for循环的效果。例子3
通常,这是编写代码的正确方法。如果您不想看到“缓存”行为,则应该编写这样的方法。
关于python - 覆盖get_queryset会导致ListView中的缓存头痛,其中数据保持陈旧,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38949071/