Code

Ticket #2939: django-distinct-values-count.diff

File django-distinct-values-count.diff, 1.6 KB (added by andrew@…, 7 years ago)

patch to add count method to ValuesQuerySet, better handling distinct case

Line 
1Index: django/db/models/query.py
2===================================================================
3--- django/db/models/query.py   (revision 4118)
4+++ django/db/models/query.py   (working copy)
5@@ -533,6 +533,31 @@
6             for row in rows:
7                 yield dict(zip(field_names, row))
8 
9+    def count(self):
10+        "Performs a SELECT COUNT() and returns the number of records as an integer."
11+        counter = self._clone()
12+        counter._order_by = ()
13+        counter._offset = None
14+        counter._limit = None
15+        counter._select_related = False
16+        select, sql, params = counter._get_sql_clause()
17+        cursor = connection.cursor()
18+
19+        # self._fields is a list of field names to fetch.
20+        if self._fields:
21+            columns = [self.model._meta.get_field(f, many_to_many=False).column for f in self._fields]
22+            column_names = ['%s.%s' % (backend.quote_name(self.model._meta.db_table), backend.quote_name(c)) for c in columns]
23+            select_spec = ', '.join(column_names)
24+        else: # Default to id_col
25+            select_spec = "%s.%s" % (backend.quote_name(self.model._meta.db_table),
26+                    backend.quote_name(self.model._meta.pk.column))
27+
28+        if self._distinct:
29+            cursor.execute("SELECT COUNT(DISTINCT(%s))" % select_spec + sql, params)
30+        else:
31+            cursor.execute("SELECT COUNT(*)" + sql, params)
32+        return cursor.fetchone()[0]
33+
34     def _clone(self, klass=None, **kwargs):
35         c = super(ValuesQuerySet, self)._clone(klass, **kwargs)
36         c._fields = self._fields[:]