aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Christie2013-03-13 11:42:12 +0000
committerTom Christie2013-03-13 11:42:12 +0000
commita798a5350a6aa3100695d41d4d37ec7e2e073bdd (patch)
tree894455f0f98283db650bd08f01d21d4260b0a44d
parent126cadf27e5956dffd44ed7330f101745fdb37d3 (diff)
downloaddjango-rest-framework-a798a5350a6aa3100695d41d4d37ec7e2e073bdd.tar.bz2
Fix duplicated database queries for paginated lists.
Closes #713.
-rw-r--r--docs/topics/release-notes.md1
-rw-r--r--rest_framework/fields.py16
-rw-r--r--rest_framework/tests/pagination.py10
3 files changed, 17 insertions, 10 deletions
diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md
index d0b46c36..4eaa42ba 100644
--- a/docs/topics/release-notes.md
+++ b/docs/topics/release-notes.md
@@ -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)
* Deal with error data nicely when deserializing lists of objects.
* 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: Workaround for Django bug causing case where `Authtoken` could be registered for cascade delete from `User` even if not installed.
diff --git a/rest_framework/fields.py b/rest_framework/fields.py
index 0a199f10..4b6931ad 100644
--- a/rest_framework/fields.py
+++ b/rest_framework/fields.py
@@ -26,14 +26,16 @@ def is_simple_callable(obj):
"""
True if the object is a callable that takes no arguments.
"""
- try:
- args, _, _, defaults = inspect.getargspec(obj)
- except TypeError:
+ function = inspect.isfunction(obj)
+ method = inspect.ismethod(obj)
+
+ if not (function or method):
return False
- else:
- len_args = len(args) if inspect.isfunction(obj) else len(args) - 1
- len_defaults = len(defaults) if defaults else 0
- return len_args <= len_defaults
+
+ args, _, _, defaults = inspect.getargspec(obj)
+ len_args = len(args) if function else len(args) - 1
+ len_defaults = len(defaults) if defaults else 0
+ return len_args <= len_defaults
def get_component(obj, attr_name):
diff --git a/rest_framework/tests/pagination.py b/rest_framework/tests/pagination.py
index 472ffcdd..3c76ca7d 100644
--- a/rest_framework/tests/pagination.py
+++ b/rest_framework/tests/pagination.py
@@ -73,7 +73,9 @@ class IntegrationTestPagination(TestCase):
GET requests to paginated ListCreateAPIView should return paginated results.
"""
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.data['count'], 26)
self.assertEqual(response.data['results'], self.data[:10])
@@ -81,7 +83,8 @@ class IntegrationTestPagination(TestCase):
self.assertEqual(response.data['previous'], None)
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.data['count'], 26)
self.assertEqual(response.data['results'], self.data[10:20])
@@ -89,7 +92,8 @@ class IntegrationTestPagination(TestCase):
self.assertNotEqual(response.data['previous'], None)
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.data['count'], 26)
self.assertEqual(response.data['results'], self.data[20:])