有人可以解释为什么重写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/

10-14 18:21
查看更多