and*_*ndy 4 django caching unit-testing transactions
我在 Django 测试中看到了一些非常令人惊讶和令人沮丧的行为。相关查找正在“找到”模型对象,但不存在模型对象。(我对这里奇怪的描述表示歉意……这种行为太奇怪了,我不知道如何描述它。这些物体存在吗?我存在吗?你存在吗??)
我需要它们存在,所以我有一个方法可以在它们不存在时创建它们。问题是,在一行中,Django 发现它们确实存在,因此它们没有被创建......然后在下一行我们可以确认不存在这样的对象。
我的测试在 test_something() 中给出了与缺少必要的 TaskMetadata 对象相关的错误。
#the model
class TaskMetadata(models.Model):
task = models.OneToOneField(ContentType)
...
#the test
class SimpleTest(TestCase):
def setUp(self):
some_utility_function()
def test_something(self):
...something that requires TaskMetadata...
def some_utility_function():
task = ...whatever...
ctype = ContentType.objects.get_for_model(task)
try:
ctype.taskmetadata
except TaskMetadata.DoesNotExist:
...create TaskMetadata...
print "Created TaskMetadata object for %s" % task.__name__
else:
print "TaskMetadata object already exists for %s" % task.__name__
print ctype.taskmetadata
print "ALL OF THEM!! %s" % TaskMetadata.objects.all()
Run Code Online (Sandbox Code Playgroud)
以及 some_utility_function() 的打印结果:
TaskMetadata object already exists for SomeTask
some task
ALL OF THEM!! [] # <-- NOTE EMPTY QUERYSET
Run Code Online (Sandbox Code Playgroud)
总之:“是的,TaskMetadata对象存在。是的,TaskMetadata对象存在。不,根本不存在TaskMetadata对象!!”
那么,说真的,这里到底发生了什么?这是缓存问题吗?我尝试清除缓存(大胆猜测;我没有在 settings.py 中配置缓存)
def setUp(self):
cache.clear()
some_utility_function()
Run Code Online (Sandbox Code Playgroud)
没有帮助。也许是交易?我很困惑。我该如何调试这个?
更新:请参阅复制该 问题的最小 django 项目。
当第一个测试用例运行时,TaskMetadata.objects.all() 不是一个空查询集(它实际上填充了对象,正如我所期望的那样);当第二个测试用例(与第一个测试用例完全相同)运行时,它是空的。
我怀疑这与清除 TaskMetadata 对象的测试用例之间的数据库刷新有关,但相关的查找被缓存,因此下次为下一个测试用例调用 some_utility_function() 时,它不会创建任何 TaskMetadata 对象。1)这合理吗?2)如何解决这个问题?3)这是一个 Django 错误,对吧?
在您的tearDown方法中,您需要调用ContentType.objects.clear_cache()。这是因为 Django 缓存了对ContentType.objects.get_for_model. 一对一的内容类型有点奇怪,所以我认为 django 不需要为此进行任何更改,特别是因为它应该是一行修复。
| 归档时间: |
|
| 查看次数: |
1321 次 |
| 最近记录: |