[英]Caching in Django's ManyToManyField
我在Django中遇到一些缓存问题。 到目前为止,我只在运行testsuite时才看到这个问题。 问题是有时候(似乎总是在第二次调用代码时发生这种情况),Django不会更新它的缓存或它变得不一致。
提取的代码与一些调试是:
class Source(models.Model):
name = models.CharField(max_length = 50)
quality = models.IntegerField(default = 0)
class Reference(models.Model):
url = models.URLField()
source = models.ForeignKey(Source)
class Meta:
ordering = ['-source__quality']
class Issue(models.Model):
references = models.ManyToManyField(Reference)
master = models.ForeignKey(Reference, related_name = 'mastered_issue_set')
def auto_create(instance):
issue = Issue.objects.create(master = instance)
print issue.references.count(), issue.references.all()
issue.references.add(instance)
print issue.references.count(), issue.references.all()
在第一次调用时,我正确地得到以下输出:
0 []
1 [<Reference: test>]
但是在第二次调用auto_create
,Django认为有一个引用,但它没有给我:
0 []
1 []
这种行为当然会打破进一步的代码。 知道这里可能出现什么问题或至少如何调试它?
PS:看起来像Reference
类的排序导致了这一点。 但我仍然不清楚为什么。
我无法用sqlite3重现。 可能是传入的Reference
实例未保存? 以下运行没有打嗝:
def auto_create(instance):
issue = Issue.objects.create(master = instance)
print issue.references.count(), issue.references.all()
assert issue.references.count()==0, "initial ref count is not null"
assert len(issue.references.all())==0, "initial ref array is not empty"
issue.references.add(instance)
print issue.references.count(), issue.references.all()
assert issue.references.count()==1, "ref count is not incremented"
assert len(issue.references.all())==1, "initial ref array is not populated"
def test_auto():
s = Source()
s.save()
r = Reference(source=s)
r.save()
auto_create(r)
最后我发现了造成这个问题的原因。 这是我自己的缓存代码而不是Django的代码。
我有自定义源管理器,它返回并缓存了一些标准源:
class SourceManager(models.Manager):
url_source = None
def get_generic(self):
if self.url_source is None:
self.url_source, created = self.get_or_create(name = 'URL', quality = 0)
return self.url_source
class Source(models.Model):
name = models.CharField(max_length = 50)
quality = models.IntegerField(default = 0)
objects = SourceManager()
这在应用程序中完美地运行 - 一旦创建了源,管理器会记住它的存在,因为源不会在其生命周期中发生变化。 然而,在测试中它们会消失,因为整个测试在单个事务中运行然后还原。
我觉得很奇怪的是models.ForeignKey
没有抱怨获取不存在的对象,但是后来出现错误,而source__quality
排序,因为底层JOIN SELECT找不到匹配的Source
对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.