覆盖get_queryset会导致ListView中的缓存问题,其中数据仍然过时

时间:2016-08-15 03:50:45

标签: python django django-templates django-queryset

有人可以解释为什么覆盖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 =&#39; abc&#39;现在不起作用

如果我没有包含方法并且只是自动调用查询集,则不会立即显示缓存和数据库更新,但我的临时数据无法到达模板。     class AppointmentListView(ListView):

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

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

示例3:没有缓存问题和r.css =&#39; abc&#39;工作得很好

最后,如果我把所有内容都放在方法中,那一切都运行正常 - 临时数据到达模板并且没有缓存。

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

1 个答案:

答案 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;你应该写这样的方法。行为。