Ticket #2939: distinct-values-count.patch
File distinct-values-count.patch, 2.8 KB (added by , 17 years ago) |
---|
-
django/db/models/query.py
235 235 236 236 cursor = connection.cursor() 237 237 if self._distinct: 238 id_col = "%s.%s" % (backend.quote_name(self.model._meta.db_table), 239 backend.quote_name(self.model._meta.pk.column)) 240 cursor.execute("SELECT COUNT(DISTINCT(%s))" % id_col + sql, params) 238 columns = ', '.join(self._get_distinct_columns()) 239 cursor.execute("SELECT COUNT(DISTINCT(%s))" % columns + sql, params) 241 240 else: 242 241 cursor.execute("SELECT COUNT(*)" + sql, params) 243 242 count = cursor.fetchone()[0] … … 251 250 252 251 return count 253 252 253 def _get_distinct_columns(self): 254 "Returns distinct columns, used for count()" 255 return ["%s.%s" % (backend.quote_name(self.model._meta.db_table), 256 backend.quote_name(self.model._meta.pk.column))] 257 254 258 def get(self, *args, **kwargs): 255 259 "Performs the SELECT and returns a single object matching the given keyword arguments." 256 260 clone = self.filter(*args, **kwargs) … … 573 577 # select_related isn't supported in values(). 574 578 self._select_related = False 575 579 580 def _get_distinct_columns(self): 581 "Returns distinct columns, used for count()" 582 if not self._fields: 583 return super(ValuesQuerySet, self)._get_distinct_columns() 584 columns = [self.model._meta.get_field(f, many_to_many=False).column 585 for f in self._fields] 586 return ['%s.%s' % (backend.quote_name(self.model._meta.db_table), 587 backend.quote_name(c)) for c in columns] 588 576 589 def iterator(self): 577 590 try: 578 591 select, sql, params = self._get_sql_clause() -
tests/modeltests/lookup/models.py
165 165 >>> list(Article.objects.filter(id=5).values()) == [{'id': 5, 'headline': 'Article 5', 'pub_date': datetime(2005, 8, 1, 9, 0)}] 166 166 True 167 167 168 # .values(*fields).distinct().count() will return the correct number of 169 # distinct records. 170 >>> Article.objects.values('pub_date').count() 171 7 172 >>> len(Article.objects.values('pub_date').distinct()) 173 5 174 >>> Article.objects.values('pub_date').distinct().count() 175 5 176 177 # And make sure it still works if no fields are passed: 178 >>> len(Article.objects.values().distinct()) 179 7 180 >>> Article.objects.values().distinct().count() 181 7 182 168 183 # Every DateField and DateTimeField creates get_next_by_FOO() and 169 184 # get_previous_by_FOO() methods. 170 185 # In the case of identical date values, these methods will use the ID as a