python - 重写 get_queryset 会导致 ListView 中的缓存问题,其中数据仍然过时

标签 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='abc' 现在不起作用

如果我不包含方法而只是自动调用查询集,则不会立即显示缓存和数据库更新,但我的临时数据不会到达模板。 类 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

示例2中,每次调用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/

相关文章:

python - 使用 AppEngine 开发服务器在 PyDev 中调试控制台

Django 运行服务器永久

python - Scrapy:创建项目返回错误

python - 计算 JSON 叶节点数

python - 在 Flask 的不同 wtfforms 中使用相同的变量名

python - 在 Django StaticLiveServerTestCase 期间在测试输出中显示服务器错误?

python - 如何强制 django 打印每个执行的 sql 查询

python - Django:模板和遍历字典

python - 如果用户有删除权限,如何检查 Django 模板?

python - django - 如何在模板中插入上传文件的内容?