Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
class QuerySetDoubleIteration(Exception):
"A QuerySet was iterated over twice, you probably want to list() it."
pass
# "Skinny" here means we use iterator by default, rather than
# ballooning in memory.
class SkinnyManager(Manager):
def get_query_set(self):
return SkinnyQuerySet(self.model, using=self._db)
class SkinnyQuerySet(QuerySet):
def __len__(self):
if getattr(self, 'has_run_before', False):
raise TypeError("SkinnyQuerySet doesn't support __len__ after __iter__, if you *only* need a count you should use .count(), if you need to reuse the results you should coerce to a list and then len() that.")
return super(SkinnyQuerySet, self).__len__()
def __iter__(self):
if self._result_cache is not None:
# __len__ must have been run
return iter(self._result_cache)
has_run_before = getattr(self, 'has_run_before', False)
if has_run_before:
raise QuerySetDoubleIteration("This SkinnyQuerySet has already been iterated over once, you should assign it to a list if you want to reuse the data.")
self.has_run_before = True
return self.iterator()
diff --git a/django_root/django/db/models/query.py b/django_root/django/db/models/query.py
index b8b2340..e679cfa 100644
--- a/django_root/django/db/models/query.py
+++ b/django_root/django/db/models/query.py
@@ -415,7 +415,7 @@ class QuerySet(object):
assert self.query.can_filter(), \
"Cannot use 'limit' or 'offset' with delete."
- del_query = self._clone()
+ del_query = self._clone(klass=QuerySet)
# The delete is actually 2 queries - one to find related objects,
# and one to delete. Make sure that the discovery of related
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment