From d123588184dfecc286e8e06e16dc0383f435c051 Mon Sep 17 00:00:00 2001 From: Malcolm Tredinnick Date: Mon, 12 Feb 2007 00:16:17 +0000 Subject: [PATCH] #fixed #2256 -- Made count() interact with slicing on QuerySets. Patch from SmileyChris. git-svn-id: http://code.djangoproject.com/svn/django/trunk@4488 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/db/models/query.py | 16 ++++++++++++++-- tests/modeltests/lookup/models.py | 11 +++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/django/db/models/query.py b/django/db/models/query.py index 7a81910715..8a784be7c8 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -197,9 +197,12 @@ class QuerySet(object): "Performs a SELECT COUNT() and returns the number of records as an integer." counter = self._clone() counter._order_by = () + counter._select_related = False + + offset = counter._offset + limit = counter._limit counter._offset = None counter._limit = None - counter._select_related = False try: select, sql, params = counter._get_sql_clause() @@ -213,7 +216,16 @@ class QuerySet(object): cursor.execute("SELECT COUNT(DISTINCT(%s))" % id_col + sql, params) else: cursor.execute("SELECT COUNT(*)" + sql, params) - return cursor.fetchone()[0] + count = cursor.fetchone()[0] + + # Apply any offset and limit constraints manually, since using LIMIT or + # OFFSET in SQL doesn't change the output of COUNT. + if offset: + count = max(0, count - offset) + if limit: + count = min(limit, count) + + return count def get(self, *args, **kwargs): "Performs the SELECT and returns a single object matching the given keyword arguments." diff --git a/tests/modeltests/lookup/models.py b/tests/modeltests/lookup/models.py index d344710bef..106c97d3b4 100644 --- a/tests/modeltests/lookup/models.py +++ b/tests/modeltests/lookup/models.py @@ -58,6 +58,17 @@ Article 4 >>> Article.objects.filter(headline__startswith='Blah blah').count() 0L +# count() should respect sliced query sets. +>>> articles = Article.objects.all() +>>> articles.count() +7L +>>> articles[:4].count() +4 +>>> articles[1:100].count() +6L +>>> articles[10:100].count() +0 + # Date and date/time lookups can also be done with strings. >>> Article.objects.filter(pub_date__exact='2005-07-27 00:00:00').count() 3L