magic-removal: Implemented QuerySet.values(). All 'lookup' unit tests pass.

git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@2181 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2006-01-30 05:38:02 +00:00
parent 913ed88397
commit e49a09731b
3 changed files with 27 additions and 33 deletions

View File

@ -43,31 +43,6 @@ class Manager(QuerySet):
if not hasattr(klass, '_default_manager') or self.creation_counter < klass._default_manager.creation_counter:
klass._default_manager = self
def get_values_iterator(self, *args, **kwargs):
# select_related and select aren't supported in get_values().
kwargs['select_related'] = False
kwargs['select'] = {}
# 'fields' is a list of field names to fetch.
try:
fields = [self.klass._meta.get_field(f).column for f in kwargs.pop('fields')]
except KeyError: # Default to all fields.
fields = [f.column for f in self.klass._meta.fields]
cursor = connection.cursor()
_, sql, params = self._get_sql_clause(True, *args, **kwargs)
select = ['%s.%s' % (backend.quote_name(self.klass._meta.db_table), backend.quote_name(f)) for f in fields]
cursor.execute("SELECT " + (kwargs.get('distinct') and "DISTINCT " or "") + ",".join(select) + sql, params)
while 1:
rows = cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE)
if not rows:
raise StopIteration
for row in rows:
yield dict(zip(fields, row))
def get_values(self, *args, **kwargs):
return list(self.get_values_iterator(*args, **kwargs))
def __get_latest(self, *args, **kwargs):
kwargs['order_by'] = ('-' + self.klass._meta.get_latest_by,)
kwargs['limit'] = 1

View File

@ -188,6 +188,27 @@ class QuerySet(object):
bulk_query._params.extend(id_list)
return dict([(obj._get_pk_val(), obj) for obj in bulk_query.iterator()])
def values(self, *fields):
# select_related and select aren't supported in values().
values_query = self._clone(_select_related=False, _select={})
# 'fields' is a list of field names to fetch.
if fields:
columns = [self.klass._meta.get_field(f, many_to_many=False).column for f in fields]
else: # Default to all fields.
columns = [f.column for f in self.klass._meta.fields]
cursor = connection.cursor()
select, sql, params = values_query._get_sql_clause(True)
select = ['%s.%s' % (backend.quote_name(self.klass._meta.db_table), backend.quote_name(c)) for c in columns]
cursor.execute("SELECT " + (self._distinct and "DISTINCT " or "") + ",".join(select) + sql, params)
while 1:
rows = cursor.fetchmany(GET_ITERATOR_CHUNK_SIZE)
if not rows:
raise StopIteration
for row in rows:
yield dict(zip(fields, row))
def dates(self, field_name, kind, order='ASC'):
"""
Returns a list of datetime objects representing all available dates

View File

@ -82,18 +82,16 @@ Traceback (most recent call last):
...
TypeError: in_bulk() got an unexpected keyword argument 'headline__startswith'
# get_values() is just like get_list(), except it returns a list of
# dictionaries instead of object instances -- and you can specify which fields
# you want to retrieve.
>>> Article.objects.get_values(fields=['headline'])
# values() returns a list of dictionaries instead of object instances -- and
# you can specify which fields you want to retrieve.
>>> list(Article.objects.values('headline'))
[{'headline': 'Article 5'}, {'headline': 'Article 6'}, {'headline': 'Article 4'}, {'headline': 'Article 2'}, {'headline': 'Article 3'}, {'headline': 'Article 7'}, {'headline': 'Article 1'}]
>>> Article.objects.get_values(pub_date__exact=datetime(2005, 7, 27), fields=['id'])
>>> list(Article.objects.filter(pub_date__exact=datetime(2005, 7, 27)).values('id'))
[{'id': 2}, {'id': 3}, {'id': 7}]
>>> Article.objects.get_values(fields=['id', 'headline']) == [{'id': 5, 'headline': 'Article 5'}, {'id': 6, 'headline': 'Article 6'}, {'id': 4, 'headline': 'Article 4'}, {'id': 2, 'headline': 'Article 2'}, {'id': 3, 'headline': 'Article 3'}, {'id': 7, 'headline': 'Article 7'}, {'id': 1, 'headline': 'Article 1'}]
>>> list(Article.objects.values('id', 'headline')) == [{'id': 5, 'headline': 'Article 5'}, {'id': 6, 'headline': 'Article 6'}, {'id': 4, 'headline': 'Article 4'}, {'id': 2, 'headline': 'Article 2'}, {'id': 3, 'headline': 'Article 3'}, {'id': 7, 'headline': 'Article 7'}, {'id': 1, 'headline': 'Article 1'}]
True
# get_values_iterator() is just like get_values(), but it's a generator.
>>> for d in Article.objects.get_values_iterator(fields=['id', 'headline']):
>>> for d in Article.objects.values('id', 'headline'):
... i = d.items()
... i.sort()
... i