Commit a798a535 by Tom Christie

Fix duplicated database queries for paginated lists.

Closes #713.
parent 126cadf2
...@@ -48,6 +48,7 @@ You can determine your currently installed version using `pip freeze`: ...@@ -48,6 +48,7 @@ You can determine your currently installed version using `pip freeze`:
* Filtering backends are now applied to the querysets for object lookups as well as lists. (Eg you can use a filtering backend to control which objects should 404) * Filtering backends are now applied to the querysets for object lookups as well as lists. (Eg you can use a filtering backend to control which objects should 404)
* Deal with error data nicely when deserializing lists of objects. * Deal with error data nicely when deserializing lists of objects.
* Extra override hook to configure `DjangoModelPermissions` for unauthenticated users. * Extra override hook to configure `DjangoModelPermissions` for unauthenticated users.
* Bugfix: Fix regression which caused extra database query on paginated list views.
* Bugfix: Fix pk relationship bug for some types of 1-to-1 relations. * Bugfix: Fix pk relationship bug for some types of 1-to-1 relations.
* Bugfix: Workaround for Django bug causing case where `Authtoken` could be registered for cascade delete from `User` even if not installed. * Bugfix: Workaround for Django bug causing case where `Authtoken` could be registered for cascade delete from `User` even if not installed.
......
...@@ -26,14 +26,16 @@ def is_simple_callable(obj): ...@@ -26,14 +26,16 @@ def is_simple_callable(obj):
""" """
True if the object is a callable that takes no arguments. True if the object is a callable that takes no arguments.
""" """
try: function = inspect.isfunction(obj)
args, _, _, defaults = inspect.getargspec(obj) method = inspect.ismethod(obj)
except TypeError:
if not (function or method):
return False return False
else:
len_args = len(args) if inspect.isfunction(obj) else len(args) - 1 args, _, _, defaults = inspect.getargspec(obj)
len_defaults = len(defaults) if defaults else 0 len_args = len(args) if function else len(args) - 1
return len_args <= len_defaults len_defaults = len(defaults) if defaults else 0
return len_args <= len_defaults
def get_component(obj, attr_name): def get_component(obj, attr_name):
......
...@@ -73,7 +73,9 @@ class IntegrationTestPagination(TestCase): ...@@ -73,7 +73,9 @@ class IntegrationTestPagination(TestCase):
GET requests to paginated ListCreateAPIView should return paginated results. GET requests to paginated ListCreateAPIView should return paginated results.
""" """
request = factory.get('/') request = factory.get('/')
response = self.view(request).render() # Note: Database queries are a `SELECT COUNT`, and `SELECT <fields>`
with self.assertNumQueries(2):
response = self.view(request).render()
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['count'], 26) self.assertEqual(response.data['count'], 26)
self.assertEqual(response.data['results'], self.data[:10]) self.assertEqual(response.data['results'], self.data[:10])
...@@ -81,7 +83,8 @@ class IntegrationTestPagination(TestCase): ...@@ -81,7 +83,8 @@ class IntegrationTestPagination(TestCase):
self.assertEqual(response.data['previous'], None) self.assertEqual(response.data['previous'], None)
request = factory.get(response.data['next']) request = factory.get(response.data['next'])
response = self.view(request).render() with self.assertNumQueries(2):
response = self.view(request).render()
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['count'], 26) self.assertEqual(response.data['count'], 26)
self.assertEqual(response.data['results'], self.data[10:20]) self.assertEqual(response.data['results'], self.data[10:20])
...@@ -89,7 +92,8 @@ class IntegrationTestPagination(TestCase): ...@@ -89,7 +92,8 @@ class IntegrationTestPagination(TestCase):
self.assertNotEqual(response.data['previous'], None) self.assertNotEqual(response.data['previous'], None)
request = factory.get(response.data['next']) request = factory.get(response.data['next'])
response = self.view(request).render() with self.assertNumQueries(2):
response = self.view(request).render()
self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['count'], 26) self.assertEqual(response.data['count'], 26)
self.assertEqual(response.data['results'], self.data[20:]) self.assertEqual(response.data['results'], self.data[20:])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment