Skip to content

Instantly share code, notes, and snippets.

@loic
Created February 4, 2015 13:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save loic/4338219ba68faec38e32 to your computer and use it in GitHub Desktop.
Save loic/4338219ba68faec38e32 to your computer and use it in GitHub Desktop.
diff --git a/django/db/models/query.py b/django/db/models/query.py
index b2d210f..0c88b50 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -165,7 +165,19 @@ class QuerySet(object):
Represents a lazy database lookup for a set of objects.
"""
- def __init__(self, model=None, query=None, using=None, hints=None):
+ def __new__(cls, *args, **kwargs):
+ queryset = super(QuerySet, cls).__new__(cls)
+ queryset.__initialized = False
+ cls.__init__(queryset, *args, **kwargs)
+ queryset.__initialized = True
+ if not queryset._cloned:
+ return queryset.init()
+ return queryset
+
+ def __init__(self, model=None, query=None, using=None, hints=None, cloned=False):
+ if self.__initialized:
+ return
+
self.model = model
self._db = using
self._hints = hints or {}
@@ -178,6 +190,10 @@ class QuerySet(object):
self._known_related_objects = {} # {rel_field, {pk: rel_obj}}
self._iterator_class = ModelIterator
self._fields = None
+ self._cloned = cloned
+
+ def init(self):
+ return self
def as_manager(cls):
# Address the circular dependency between `Queryset` and `Manager`.
@@ -1044,7 +1060,7 @@ class QuerySet(object):
query = self.query.clone()
if self._sticky_filter:
query.filter_is_sticky = True
- clone = self.__class__(model=self.model, query=query, using=self._db, hints=self._hints)
+ clone = self.__class__(model=self.model, query=query, using=self._db, hints=self._hints, cloned=True)
clone._for_write = self._for_write
clone._prefetch_related_lookups = self._prefetch_related_lookups[:]
clone._known_related_objects = self._known_related_objects
diff --git a/tests/custom_managers/models.py b/tests/custom_managers/models.py
index d4ca730..e8ebc1a 100644
--- a/tests/custom_managers/models.py
+++ b/tests/custom_managers/models.py
@@ -70,14 +70,14 @@ class DeconstructibleCustomManager(BaseCustomManager.from_queryset(CustomQuerySe
super(DeconstructibleCustomManager, self).__init__(a)
-class FunPeopleManager(models.Manager):
- def get_queryset(self):
- return super(FunPeopleManager, self).get_queryset().filter(fun=True)
+class FunPeopleQuerySet(models.QuerySet):
+ def init(self):
+ return self.filter(fun=True)
-class BoringPeopleManager(models.Manager):
- def get_queryset(self):
- return super(BoringPeopleManager, self).get_queryset().filter(fun=False)
+class BoringPeopleQuerySet(models.QuerySet):
+ def init(self):
+ return self.filter(fun=False)
@python_2_unicode_compatible
@@ -92,8 +92,8 @@ class Person(models.Model):
favorite_thing = GenericForeignKey('favorite_thing_type', 'favorite_thing_id')
objects = PersonManager()
- fun_people = FunPeopleManager()
- boring_people = BoringPeopleManager()
+ fun_people = FunPeopleQuerySet.as_manager()
+ boring_people = BoringPeopleQuerySet.as_manager()
custom_queryset_default_manager = CustomQuerySet.as_manager()
custom_queryset_custom_manager = CustomManager('hello')
@@ -113,7 +113,7 @@ class FunPerson(models.Model):
favorite_thing_id = models.IntegerField(null=True)
favorite_thing = GenericForeignKey('favorite_thing_type', 'favorite_thing_id')
- objects = FunPeopleManager()
+ objects = FunPeopleQuerySet.as_manager()
def __str__(self):
return "%s %s" % (self.first_name, self.last_name)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment