我在Django应用程序中有这个看似简单的测试用例,但失败了:
def test_matches(self):
# setup code...
matches = tournament.match_set.order_by('match_id')
matches[0].winner = 'a'
matches[0].save()
self.assertEqual(matches[0].winner, 'a')
有什么问题?
答案 0 :(得分:4)
问题是matches
不仅仅是一个列表,而是QuerySet
:索引和切片QuerySet
访问数据库,因此每个matches[0]
都返回一个新的匹配。因此,matches[0].save()
会保存未修改的对象。
正如@Wtower所说,找到相关文档here
这应该写的方式是:
m = matches[0]
m.winner = 'a'
m.save()
self.assertEqual(matches[0].winner, 'a')
交替地,强制评估QuerySet
,如果这是你想要的:
matches = list(tournament.match_set.order_by('match_id'))
或更好,如果您可以识别数据库中的匹配项:
matches.filter(match_id=0).update(winner=0)
这种方式更短,更新到位而不将数据加载到python中,从而消除了可能的竞争条件。但是,match_id
的过滤(通常)与索引到QuerySet
的过程不同。 (无法更新像QuerySet
这样的切片matches[0:1]