그래서 두 사람 체스 웹 사이트 인 지금 처음으로 장고 프로젝트를 구축하고 있습니다. 나는 거의 끝났어. 이제 시험을 쓰고있어. 이 프로젝트에는 플레이어와 게임이라는 두 가지 독창적 인 모델이 있습니다. 플레이어 모델은 사용자 모델 인 Player.user에 대해 일대일 필드를 가지고 있으며 게임에 대한 외래 키인 Player.current_game은 플레이어가 현재있는 게임 인스턴스를 나타냅니다. Game.draw_offered CharField는 값 " (기본 값), "w"또는 "b"로 표시되며 제공 여부와 해당 플레이어의 색상을 나타냅니다. 나는 다음을 수행하는 테스트 케이스가 있습니다Django 외래 키가 작동하는 방식을 이해하려고 시도했습니다.
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을 참조하면 장고는 데이터베이스 조회를 수행하고 최신 필드가있는 Game 인스턴스를 반환합니다. self.game과 self.player2.current_game이 데이터베이스의 동일한 게임 레코드에 해당하고 self.game.refresh_from_db()가 방금 호출 되었기 때문에 self.game.draw_offered == self.player2.current_game.draw_offered라고 생각할 것입니다. True로 평가됩니다. 두 게임 인스턴스는 모두 동일한 데이터베이스 레코드를 참조하며 최신 필드가 있습니다. assertion pass를 만들기 위해 self.player2.current_game.refresh_from_db()를 호출해야한다는 사실은 장고 외래 키에 대한 나의 이해에 따라 self.player2.current_game이 자동으로 업데이트되어야한다. 데이터베이스로
여기 내 이해가있다. x = self.player2라고 쓸 때.current_game, x의 필드는 데이터베이스에 자동으로 업데이트됩니다. Django는 외래 키 속성을 통해 객체를 참조 할 때마다 데이터베이스 조회를 수행하기 때문에 데이터베이스에 자동으로 업데이트됩니다. 답은 self.player2.current_game이 메모리에 저장된 객체를 가리키며 데이터베이스와 아무 관련이없는 표준 Python 속성 참조와 비슷하다는 것을 암시하는 것으로 보입니다. 어느 것이 옳은가요? – Vik78
아니요, 제 3 단락의 시작 부분에서 말씀 드렸듯이 이해가 잘못되었습니다. 처음에 객체의 외래 키 속성을 참조하면 Django는 데이터베이스로 가져와 그것을 가져옵니다. 그러나 부모 개체에 저장하므로 후속 참조로 인해 데이터베이스 조회가 더 이상 발생하지 않습니다. (마찬가지로 처음에'select_related'를 사용했다면 Django는 처음부터 관련된 객체를 얻고 캐쉬하기 위해 JOIN을 할 것이므로 db lookup은 수행되지 않을 것입니다.) 여러분의 경우 다시, Django는 당신이 그것을 만들었을 때, db lookup을 할 필요가 없다. –
{player = request.user.player}를 설정하고 {game = player.current_game}을 (를) 요청하는 많은 조회수가 있으며 그 동작은 {game}의 속성에 따라 다릅니다. {game}의 속성이 최신인지 확인하기 위해 refresh_from_db() 문을 포함하도록보기를 다시 작성해야하거나 외래 키를 참조하여 데이터베이스 조회가 수행 되니? 내 프로젝트가 정상적으로 작동하고있는 것 같아서 {game}의 속성이 오래 되었다면 문제가 발생할 것으로 예상됩니다. 도와 줘서 고마워, btw. – Vik78