Ticket #2482: valuelist.diff
File valuelist.diff, 4.0 KB (added by , 18 years ago) |
---|
-
django/db/models/query.py
308 308 def values(self, *fields): 309 309 return self._clone(klass=ValuesQuerySet, _fields=fields) 310 310 311 def valuelist(self, *fields): 312 return self._clone(klass=ValueListQuerySet, _fields=fields) 313 311 314 def dates(self, field_name, kind, order='ASC'): 312 315 """ 313 316 Returns a list of datetime objects representing all available dates … … 509 512 return select, " ".join(sql), params 510 513 511 514 class ValuesQuerySet(QuerySet): 512 def iterator(self): 515 def get_columns(self): 516 if self._fields: 517 return [self.model._meta.get_field(f, many_to_many=False).column for f in self._fields] 518 else: 519 return [f.column for f in self.model._meta.fields] 520 521 def get_field_names(self): 522 return self._fields and self._fields or [f.attname for f in self.model._meta.fields] 523 524 def get_values_cursor(self): 513 525 # select_related and select aren't supported in values(). 514 526 self._select_related = False 515 527 self._select = {} 516 528 517 # self._fields is a list of field names to fetch. 518 if self._fields: 519 columns = [self.model._meta.get_field(f, many_to_many=False).column for f in self._fields] 520 field_names = self._fields 521 else: # Default to all fields. 522 columns = [f.column for f in self.model._meta.fields] 523 field_names = [f.attname for f in self.model._meta.fields] 524 529 columns = self.get_columns() 525 530 cursor = connection.cursor() 526 531 select, sql, params = self._get_sql_clause() 527 532 select = ['%s.%s' % (backend.quote_name(self.model._meta.db_table), backend.quote_name(c)) for c in columns] 528 533 cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params) 534 return cursor 535 536 def iterator(self): 537 cursor = self.get_values_cursor() 538 field_names = self.get_field_names() 529 539 while 1: 530 540 rows = cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE) 531 541 if not rows: … … 538 548 c._fields = self._fields[:] 539 549 return c 540 550 551 class ValueListQuerySet(ValuesQuerySet): 552 def iterator(self): 553 cursor = self.get_values_cursor() 554 while 1: 555 rows = cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE) 556 if not rows: 557 raise StopIteration 558 for row in rows: 559 if len(row) == 1: 560 yield row[0] 561 else: 562 yield tuple(row) 563 564 def _clone(self, klass=None, **kwargs): 565 c = super(ValueListQuerySet, self)._clone(klass, **kwargs) 566 c._fields = self._fields[:] 567 return c 568 541 569 class DateQuerySet(QuerySet): 542 570 def iterator(self): 543 571 from django.db.backends.util import typecast_timestamp -
tests/modeltests/lookup/models.py
124 124 >>> list(Article.objects.filter(id=5).values()) == [{'id': 5, 'headline': 'Article 5', 'pub_date': datetime(2005, 8, 1, 9, 0)}] 125 125 True 126 126 127 # valuelist() returns a list of object field values instead of object instances. Like 128 # values(), you can specify the fields whose values you want to retrieve. 129 >>> list(Article.objects.order_by('id').valuelist('id')) == [1, 2, 3, 4, 5, 6, 7] 130 True 131 132 # if you specify more than one field, a list of tuples of field values is returned 133 >>> for t in Article.objects.order_by('id').valuelist('id', 'headline'): 134 ... t 135 (1, 'Article 1') 136 (2, 'Article 2') 137 (3, 'Article 3') 138 (4, 'Article 4') 139 (5, 'Article 5') 140 (6, 'Article 6') 141 (7, 'Article 7') 142 127 143 # Every DateField and DateTimeField creates get_next_by_FOO() and 128 144 # get_previous_by_FOO() methods. 129 145 # In the case of identical date values, these methods will use the ID as a