所以我现在正在构建我的第一个 Django 项目,一个双人国际象棋网站。我快完成了,现在我正在编写测试。该项目有两个原始模型:玩家和游戏。Player 模型与 User 模型具有一对一的字段 Player.user 和 Game 的外键 Player.current_game,它指示玩家当前所在的游戏实例。 Game.draw_offered CharField 采用值 "" (默认值)、“w”或“b”,指示是否已提供平局以及提供平局的玩家的颜色。我有一个执行以下操作的测试用例:
class Draw_ViewTestCase(TestCase):
def setUp(self):
self.user1 = User.objects.create_user(username="Test_User_1", password="test1")
self.user2 = User.objects.create_user(username="Test_User_2", password="test2")
self.factory = RequestFactory()
self.game = Game.objects.create()
self.player1 = Player.objects.create(user=self.user1, current_game=self.game, color="w")
self.player2 = Player.objects.create(user=self.user2, current_game=self.game, color="b")
def test_draw(self):
request = self.factory.get(reverse('draw'))
request.user = self.user1
#The draw view changes the draw_offered field of the player's current game to the player's color, and saves the current_game to the database
response = draw(request)
self.game.refresh_from_db()
assert self.game.draw_offered == self.player1.color
assert self.game == self.player2.current_game
#self.player2.current_game.refresh_from_db()
assert self.game.draw_offered == self.player2.current_game.draw_offered
除了最后一个,所有的断言都通过了,但是如果你取消倒数第二行的注释,它就会通过。
这是怎么回事?据我了解,当您引用外键属性 self.player2.current_game 时,Django 会执行数据库查找并返回带有最新字段的 Game 实例。由于 self.game 和 self.player2.current_game 对应数据库中相同的 Game 记录,而 self.game.refresh_from_db() 只是被调用,你会认为 self.game.draw_offered == self.player2.current_game.draw_offered将评估为 True——两个 Game 实例都引用相同的数据库记录并具有最新的字段。我必须调用 self.player2.current_game.refresh_from_db() 以使断言通过这一事实对我来说没有意义——根据我对 Django Foreign Keys 的理解,self.player2.current_game 应该自动更新与数据库。