Fixed 19895 -- Made second iteration over invalid queryset raise an exception too

When iteration over a queryset raised an exception, the result cache
remained initialized with an empty list, so subsequent iterations returned
an empty list instead of raising an exception
This commit is contained in:
Grzegorz Nosek 2013-02-23 20:59:09 +01:00 committed by Jacob Kaplan-Moss
parent 4c05fdb467
commit 2cd0edaa47
2 changed files with 19 additions and 2 deletions

View File

@ -104,7 +104,7 @@ class QuerySet(object):
len(self)
if self._result_cache is None:
self._iter = self.iterator()
self._iter = self._safe_iterator(self.iterator())
self._result_cache = []
if self._iter:
return self._result_iter()
@ -341,6 +341,18 @@ class QuerySet(object):
yield obj
def _safe_iterator(self, iterator):
# ensure result cache is cleared when iterating over a queryset
# raises an exception
try:
for item in iterator:
yield item
except StopIteration:
raise
except Exception:
self._result_cache = None
raise
def aggregate(self, *args, **kwargs):
"""
Returns a dictionary containing the calculations (aggregation)

View File

@ -2,7 +2,7 @@ from __future__ import absolute_import, unicode_literals
from datetime import datetime
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned, FieldError
from django.db.models.fields import Field, FieldDoesNotExist
from django.db.models.query import QuerySet, EmptyQuerySet, ValuesListQuerySet
from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature
@ -686,3 +686,8 @@ class ModelTest(TestCase):
Article.objects.create(headline='foo', pub_date=datetime.now())
with self.assertNumQueries(0):
self.assertEqual(len(Article.objects.none().distinct('headline', 'pub_date')), 0)
def test_invalid_qs_list(self):
qs = Article.objects.order_by('invalid_column')
self.assertRaises(FieldError, list, qs)
self.assertRaises(FieldError, list, qs)