gpt4 book ai didi

python - 在django中确定属性是否为 `DeferredAttribute`

转载 作者:IT老高 更新时间:2023-10-28 21:13:39 25 4
gpt4 key购买 nike

背景


我在 Django Cache Machine 中发现了一个相当严重的错误,它在从 Django 1.4 升级到 1.7 后导致它的失效逻辑失去理智。

该错误被本地化为在扩展缓存机器的 CachingMixin 的模型上调用 only()。它会导致深度递归,偶尔会破坏堆栈,但会创建巨大的 flush_lists 缓存机器用于在 ForeignKey 关系中的模型的双向失效。

class MyModel(CachingMixin):
id = models.CharField(max_length=50, blank=True)
nickname = models.CharField(max_length=50, blank=True)
favorite_color = models.CharField(max_length=50, blank=True)
content_owner = models.ForeignKey(OtherModel)

m = MyModel.objects.only('id').all()

bug


该错误出现在以下几行中(https://github.com/jbalogh/django-cache-machine/blob/f827f05b195ad3fc1b0111131669471d843d631f/caching/base.py#L253-L254)。在这种情况下,selfMyModel 的一个实例,具有延迟和非延迟属性的混合:

    fks = dict((f, getattr(self, f.attname)) for f in self._meta.fields
if isinstance(f, models.ForeignKey))

Cache Machine 跨 ForeignKey 关系进行双向失效。它通过遍历 Model 中的所有字段并在缓存中存储一​​系列指针来实现这一点,这些指针指向在相关对象失效时需要失效的对象。

在 Django ORM 中使用 only() 实现了一些元编程魔法,它使用 Django 的 DeferredAttribute 实现覆盖未获取的属性。在正常情况下,对 favorite_color 的访问会调用 DeferredAttribute.__get__( https://github.com/django/django/blob/18f3e79b13947de0bda7c985916d5a04e28936dc/django/db/models/query_utils.py#L121-L146 ) 并从结果缓存或数据源中获取属性。它通过获取有问题的 Model 的未延迟表示并在其上调用另一个 only() 查询来做到这一点。

这是在 Model 中循环外键并访问它们的值时出现的问题,Cahine Machine 引入了无意的递归。延迟属性上的 getattr(self, f.attname) 会导致获取已应用 CachingMixin 并具有延迟属性的 Model .这将重新开始整个缓存过程。

问题


我想打开一个 PR 来解决这个问题,我相信这个问题的答案就像跳过延迟属性一样简单,但我不知道该怎么做,因为访问属性会导致提取过程开始.

如果我只有一个 Model 实例的句柄,其中混合了延迟和非延迟属性,有没有办法确定属性是否是 DeferredAttribute 没有访问它?

    fks = dict((f, getattr(self, f.attname)) for f in self._meta.fields
if (isinstance(f, models.ForeignKey) and <f's value isn't a Deferred attribute))

最佳答案

以下是检查字段是否被延迟的方法:

from django.db.models.query_utils import DeferredAttribute

is_deferred = isinstance(model_instance.__class__.__dict__.get(field.attname), DeferredAttribute):

取自:https://github.com/django/django/blob/1.9.4/django/db/models/base.py#L393

关于python - 在django中确定属性是否为 `DeferredAttribute`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28222469/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com