标签: django-cache-machine

确定django中的属性是否为"DeferredAttribute"

上下文


我在Django Cache Machine中找到了一个相当关键的错误,它导致它的失效逻辑在从Django 1.4升级到1.7后失去了理智.

该错误本地化为only()扩展缓存机器的模型的调用CachingMixin.它导致深度递归,偶尔会破坏堆栈,但否则会产生巨大的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)
Run Code Online (Sandbox Code Playgroud)
m = MyModel.objects.only('id').all()
Run Code Online (Sandbox Code Playgroud)

错误


该错误发生在以下行中(https://github.com/jbalogh/django-cache-machine/blob/f827f05b195ad3fc1b0111131669471d843d631f/caching/base.py#L253-L254).在这种情况下,self是一个MyModel混合了延迟和未延迟属性的实例:

    fks = dict((f, getattr(self, f.attname)) for f in self._meta.fields
                if isinstance(f, models.ForeignKey))
Run Code Online (Sandbox Code Playgroud)

Cache Machine跨ForeignKey关系执行双向失效.它通过循环遍历a中的所有字段来实现Model并在缓存中存储一​​系列指针来指针指向当有问题的对象无效时需要无效的对象.

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

这是循环遍历外键Model并访问其值时的问题,Cachine Machine引入了无意的递归.getattr(self, …

python django django-models django-orm django-cache-machine

17
推荐指数
2
解决办法
7542
查看次数

为什么Django会返回过时的缓存数据?

我有两个Django模型,如下所示,MyModel1&MyModel2:

class MyModel1(CachingMixin, MPTTModel):
    name = models.CharField(null=False, blank=False, max_length=255)
    objects = CachingManager()

    def __str__(self):
        return "; ".join(["ID: %s" % self.pk, "name: %s" % self.name, ] )

class MyModel2(CachingMixin, models.Model):
    name = models.CharField(null=False, blank=False, max_length=255)
    model1 = models.ManyToManyField(MyModel1, related_name="MyModel2_MyModel1")
    objects = CachingManager()

    def __str__(self):
        return "; ".join(["ID: %s" % self.pk, "name: %s" % self.name, ] )
Run Code Online (Sandbox Code Playgroud)

MyModel2有一个ManyToMany字段来MyModel1授权model1

现在看看当我向这个ManyToMany字段添加一个新条目时会发生什么.据Django说,它没有效果:

>>> m1 = MyModel1.objects.all()[0]
>>> m2 = MyModel2.objects.all()[0]
>>> m2.model1.all()
[]
>>> m2.model1.add(m1)
>>> m2.model1.all() …
Run Code Online (Sandbox Code Playgroud)

python django django-cache django-cache-machine

9
推荐指数
1
解决办法
968
查看次数