有人可以解释为什么覆盖get_queryset
并通过self
引用查询集会完全缓存页面吗?在对数据库进行更新显示之前,我需要等待5分钟或更长时间。
我试图将临时值保存到每个对象并将其传递给模板。
我在示例3中让所有事情都工作得很好,但我真的不明白我做了什么才能让它发挥作用,所以任何见解都会很棒!
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
如果我没有包含方法并且只是自动调用查询集,则不会立即显示缓存和数据库更新,但我的临时数据无法到达模板。 class AppointmentListView(ListView):
queryset = Appointment.objects.prefetch_related('client','patients')
for r in queryset:
r.css = 'abc' #<- NOT passed to template
最后,如果我把所有内容都放在方法中,那一切都运行正常 - 临时数据到达模板并且没有缓存。
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
答案 0 :(得分:2)
您看到的行为是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
是一个类变量,因此只会被评估一次(这就是为什么你会看到&#34;缓存&#34;行为)。对get_queryset
的后续调用将返回最初评估的qs
变量。
示例2
您没有覆盖get_queryset
,这意味着使用ListView.get_queryset
实施。
Django ListView.get_queryset
在评估之前复制了queryset
- 这就是为什么你没有看到&#34;缓存&#34;。但是,由于复制了查询集,因此抛弃了for循环的效果。
示例3
这通常是编写代码的正确方法。如果你不想看到&#34;缓存&#34;你应该写这样的方法。行为。