From 58e7bbc8ecad8016cc18f7dbd31b235cb515b785 Mon Sep 17 00:00:00 2001 From: Ofir Ovadia Date: Wed, 4 Feb 2015 16:08:41 +0200 Subject: [PATCH] Prefetching the user object when getting the token in TokenAuthentication. Since the user object is fetched 4 lines after getting Token from the database, this removes a DB query for each token-authenticated request. --- rest_framework/authentication.py | 2 +- tests/test_authentication.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py index 4832ad33bc..f7601fb123 100644 --- a/rest_framework/authentication.py +++ b/rest_framework/authentication.py @@ -167,7 +167,7 @@ def authenticate(self, request): def authenticate_credentials(self, key): try: - token = self.model.objects.get(key=key) + token = self.model.objects.select_related('user').get(key=key) except self.model.DoesNotExist: raise exceptions.AuthenticationFailed('Invalid token') diff --git a/tests/test_authentication.py b/tests/test_authentication.py index 44837c4efd..caabcc2141 100644 --- a/tests/test_authentication.py +++ b/tests/test_authentication.py @@ -202,6 +202,12 @@ def test_post_json_passing_token_auth(self): response = self.csrf_client.post('/token/', {'example': 'example'}, format='json', HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, status.HTTP_200_OK) + def test_post_json_makes_one_db_query(self): + """Ensure that authenticating a user using a token performs only one DB query""" + auth = "Token " + self.key + func_to_test = lambda: self.csrf_client.post('/token/', {'example': 'example'}, format='json', HTTP_AUTHORIZATION=auth) + self.assertNumQueries(1, func_to_test) + def test_post_form_failing_token_auth(self): """Ensure POSTing form over token auth without correct credentials fails""" response = self.csrf_client.post('/token/', {'example': 'example'})