From 42dc3b9ba247ea035e2d2855917592bdda5f5812 Mon Sep 17 00:00:00 2001 From: Malcolm Tredinnick Date: Wed, 23 Apr 2008 09:53:22 +0000 Subject: [PATCH] queryset-refactor: Fixed the interaction between extra(select=...) and valuelist(). Fixed #7053. git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@7446 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/db/models/query.py | 12 ++++++++++-- tests/modeltests/lookup/models.py | 7 +++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/django/db/models/query.py b/django/db/models/query.py index 3e8b570a73..5cffbe814c 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -557,13 +557,21 @@ class ValuesQuerySet(QuerySet): class ValuesListQuerySet(ValuesQuerySet): def iterator(self): - self.field_names.extend([f for f in self.query.extra_select.keys()]) + self.query.trim_extra_select(self.extra_names) if self.flat and len(self._fields) == 1: for row in self.query.results_iter(): yield row[0] - else: + elif not self.query.extra_select: for row in self.query.results_iter(): yield row + else: + # When extra(select=...) is involved, the extra cols come are + # always at the start of the row, so we need to reorder the fields + # to match the order in self._fields. + names = self.query.extra_select.keys() + self.field_names + for row in self.query.results_iter(): + data = dict(zip(names, row)) + yield tuple([data[f] for f in self._fields]) def _clone(self, *args, **kwargs): clone = super(ValuesListQuerySet, self)._clone(*args, **kwargs) diff --git a/tests/modeltests/lookup/models.py b/tests/modeltests/lookup/models.py index a18be968aa..d134fb5265 100644 --- a/tests/modeltests/lookup/models.py +++ b/tests/modeltests/lookup/models.py @@ -180,6 +180,13 @@ True >>> Article.objects.valueslist('id', flat=True).order_by('id') [1, 2, 3, 4, 5, 6, 7] +>>> Article.objects.extra(select={'id_plus_one': 'id+1'}).order_by('id').valueslist('id') +[(1,), (2,), (3,), (4,), (5,), (6,), (7,)] +>>> Article.objects.extra(select={'id_plus_one': 'id+1'}).order_by('id').valueslist('id_plus_one', 'id') +[(2, 1), (3, 2), (4, 3), (5, 4), (6, 5), (7, 6), (8, 7)] +>>> Article.objects.extra(select={'id_plus_one': 'id+1'}).order_by('id').valueslist('id', 'id_plus_one') +[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8)] + >>> Article.objects.valueslist('id', 'headline', flat=True) Traceback (most recent call last): ...