如何禁用Django查询caching?

在我的Django应用程序中,我反复在我的数据库上运行相同的查询(例如,每隔10秒)。 然后我创build一个MD5总和我收到的查询集,并将其与上一次运行中创build的MD5总和进行比较。 如果两者相同,则数据没有改变,网页不需要更新。

当我这样做时,数据库中的数据可能会改变。

但是,查询返回相同的查询集,显然是由于查询caching 。

我怎样才能禁用查询caching并明确地执行对数据库的查询?

我遇到了一些我认为是某种caching的行为,但事实certificate是数据库交易欺骗了我。

我遇到了问题,在另一个进程中,项目被添加到数据库,我想监视另一个进程的进度,所以我打开了一个django shell,并发布以下内容:

>>> MyData.objects.count() 74674 >>> MyData.objects.count() 74674 

价值没有改变,即使它实际上在数据库中。 我意识到,至less在我有MySQL和Django的设置,我在一个事务中,只会看到我打开交易时的数据库的“快照”的方式。

由于在Django的视图,我已经定义了autocommit行为,这是没有问题的每个视图只看到一个快照,下一次视图被称为它将在不同的事务。 但是对于一段不是自动提交的代码,除了在这个事务中所做的更改之外,它不会在db中看到任何更改。

只是以为我会把这个答案抛给任何可能遇到这种情况的人。

为了解决,提交你的交易,可以这样手动完成:

 >> from django.db import transaction >> transaction.enter_transaction_management() >> transaction.commit() # Whenever you want to see new data 

查询caching仅适用 QuerySet。 换句话说,如果你计算两次相同的queryset对象,查询caching将会运行。 但是,如果你每10秒钟做一次查询,大概这是通过每次都会产生一个新进程的cron,所以Django没有办法caching任何东西。

如果您反复执行完全相同的查询,则数据库自己的caching可能会开始运行。 您应该查看DBMS的文档以了解如何正确pipe理该文档。

您提供给Django文档的链接意味着以下内容:

 >>> print [e.headline for e in Entry.objects.all()] >>> print [e.pub_date for e in Entry.objects.all()] 

创build两个查询到数据库,而:

 >>> queryset = Poll.objects.all() >>> print [p.headline for p in queryset] # Evaluate the query set. >>> print [p.pub_date for p in queryset] # Re-use the cache from the evaluation. 

使用查询caching,因为您正在访问相同的评估结果。

非常感谢你的回答,你的回复让我退后一步,重新思考。

为了在DBMS级别上testingcaching,我离开了Django,并使用了一个shell脚本,我无论如何都可以周期性地从SQLite数据库中查询数据,而我在第二个shell会话中添加了数据。 在添加新数据后,新数据在周期性查询中显示出来,所以在这里没有查询caching。

这缩小到了Django的一部分。 所涉及的代码不是很复杂,一点点的日志输出和一个代码审查揭示了这个问题:用于获取查询集用于创buildMD5总和的查询有一个错误,总是空的。 所以MD5总是一样的。 确实看起来像一个caching结果 – 数据正在改变,但查询集保持不变。 该问题没有在应用程序中显示,因为使用了不同的查询来获取那里显示的数据。

获得的经验:如果你完全困惑,退后一步,重新考虑你的假设。

再次感谢! 🙂

我在django 1.8版本遇到这个问题。 有没有直接的方法来做到这一点,但有一些方法可以通过访问数据库而不是caching来重新评估和执行查询集。 我在Django Queryset文档中find它

我用其中之一来处理我的问题。 它是querysets的exists()函数。 len()repr()也可以使用。 他们也为我工作。

 queryset = ModelClass.objects.filter(....) queryset.exists() #or len(queryset) #or repr(queryset) #Now queryset is re-evaluated.