python - 在 Django 中,给定一个模型实例,我如何确定 ForeignKey 字段是否已完全水合?
问题描述
语境:
我维护遗留的 Django 代码。在许多情况下,我的代码会接收多个模型对象,每个模型对象都有一个 ForeignKey 或一个手动缓存的属性,代表相同的数据实体。因此引用的数据实体不会改变。但是,并非我收到的所有对象都访问过这些 ForeignKey 字段或缓存的属性,因此这些对象上可能不存在数据,尽管它会在首次访问时延迟加载。
我不容易访问/控制声明模型的代码。
我想找到我拥有的任何一个具有预备缓存的对象,这样我就可以避免访问数据库来检索我所追求的数据(如果没有,我会在必要时这样做)。这是因为该数据的获取足够频繁以至于导致性能问题。
Django 1.6,Python 2.7。
问题
我可以询问我们手动缓存的字段并说internal_is_cached(instance, 'fieldname')
而不运行查询。但是,我不能对ForeignKey
字段执行此操作。
假设我在 Django 中有一个模型类Foo
,如下所示:
class Foo(models.Model):
bar = models.ForeignKey('BarModel')
问题
如果我从某个地方获得模型的实例Foo
,但我不知道是否bar
曾经调用过它,或者是否已经急切地获取它,我如何确定读取instance.bar
是否会查询数据库?
换句话说,我想从外部确定任意模型的内部缓存是否为给定的 准备好ForeignKey
,而关于该模型的状态或来源的其他知识为零。
我试过的
我尝试使用 Django 缓存进行模型缓存,以围绕该问题进行“最终运行”。相关数据的获取足够频繁,以至于它们对我们的缓存系统造成了不可持续的负载。
我尝试了这个问题的各种解决方案。它们适用于修改后的模型,但似乎不适用于尚未变异的模型——我对模型的“延迟加载”状态感兴趣,而不是“待修改”状态。其中许多解决方案也不适用,因为它们需要更改模型继承或行为,我希望尽可能避免(政治)。
这个问题看起来很有希望,但它需要控制模型初始阅读器过程。我的代码收到的模型对象可能来自任何地方。
- 与 [this writeup] 中描述的事后缓存启动相反,在测试中对我有用。但是,它依赖于模型对象的
_default_manager
内部方法,这对于我们生产中的一些(高度定制的)模型对象来说是不准确的字段引用。其中一些很奇怪,如果可能的话,我更愿意坚持使用记录在案的(或至少是稳定的且不经常被绕过的)API。
- 与 [this writeup] 中描述的事后缓存启动相反,在测试中对我有用。但是,它依赖于模型对象的
解决方案
感谢 @Daniel Roseman的澄清。
使用 Django 版本 <= 1.6(您的情况下的工作解决方案)
您可以检查您foo_instance
是否有一个_bar_cache
属性:
hasattr(foo_instance, "_bar_cache")
就像这里解释的一样。
使用 Django 版本 > 1.6
缓存的字段现在存储在属性中的fields_cache
dict 中:_state
foo_instance._state.fields_cache["bar"]
推荐阅读
- c# - 如何在 SQL Server 2008 中将空值添加到外键列?
- pandas - 从聚合函数制作数据框时无法指定列名
- mongodb - 如何在 MongoDB 文档中查找索引数组
- java - 调用另一个方法时调用一个方法?
- c++ - 从常量初始化 char 数组
- spring-boot - 使用 datasource-proxy 有没有办法不记录查询参数?
- python - AES 加密问题。无法用正确的密钥解密
- excel - 基于循环遍历具有 300 万行的 txt 文件中的值的 excel 匹配值的文本匹配 [慢]
- firebase - Firebase - 从数据库/firestore 数据执行分析
- windows - Windows(窗体)应用项目建议