Skip to content

Instantly share code, notes, and snippets.

@kezabelle
Last active April 7, 2017 10:44
Show Gist options
  • Save kezabelle/88b6c34ea31e5e7b7f6920e8e81081d7 to your computer and use it in GitHub Desktop.
Save kezabelle/88b6c34ea31e5e7b7f6920e8e81081d7 to your computer and use it in GitHub Desktop.
Playing with the idea of a queryset which cannot be accidentally Evaluated, only cloned.
class UnevaluableQuerySet(QuerySet):
def __init__(self, *a, **kw):
super(UnevaluableQuerySet, self).__init__(*a, **kw)
self._frozen = False
def freeze(self):
clone = self._clone()
clone._frozen = True
return clone
def unfreeze(self):
clone = self._clone()
return clone
def _fetch_all(self):
if hasattr(self, '_frozen') and self._frozen is True:
raise ValueError("Frozen!")
return super(UnevaluableQuerySet, self)._fetch_all()
def _clone(self, **kwargs):
clone = super(UnevaluableQuerySet, self)._clone(**kwargs)
clone._frozen = False
return clone
converts_to_manager = UnevaluableQuerySet.as_manager()
usage = MyModel.objects.do_something().do_another_expensive_thing().freeze()
[x for x in usage] # ValueError
[x for x in usage.all()] # Is fine.
[x for x in usage.unfreeze()] # Is also fine.
print(usage) # is also fine because __getitem__ takes a _clone
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment