PassThroughManager calls superclass get_query_set.

As discussed in #31, PassThroughManager and
PassThroughManager.for_queryset_class() would ignore the superclass
version of `get_query_set`.
This commit is contained in:
Andy Freeland 2013-05-24 15:24:37 -04:00
parent 1921809d95
commit 7e381179e4
5 changed files with 29 additions and 10 deletions

View file

@ -17,3 +17,4 @@ Simon Meers <simon@simonmeers.com>
sayane
Trey Hunner <trey@treyhunner.com>
zyegfryed
Andy Freeland <andy@andyfreeland.net>

View file

@ -4,6 +4,9 @@ CHANGES
tip (unreleased)
----------------
- ``PassThroughManager.for_queryset_class()`` no longer ignores superclass
``get_query_set``.
- Fixed ``InheritanceManager`` bug with grandchildren in Django 1.6. Thanks
CrazyCasta.

View file

@ -164,11 +164,10 @@ class PassThroughManager(models.Manager):
return getattr(self.get_query_set(), name)
def get_query_set(self):
qs = super(PassThroughManager, self).get_query_set()
if self._queryset_cls is not None:
kwargs = {'model': self.model}
kwargs['using'] = self._db
return self._queryset_cls(**kwargs)
return super(PassThroughManager, self).get_query_set()
qs = qs._clone(klass=self._queryset_cls)
return qs
@classmethod
def for_queryset_class(cls, queryset_cls):
@ -181,9 +180,8 @@ def create_pass_through_manager_for_queryset_class(base, queryset_cls):
return super(_PassThroughManager, self).__init__()
def get_query_set(self):
kwargs = {}
kwargs["using"] = self._db
return queryset_cls(self.model, **kwargs)
qs = super(_PassThroughManager, self).get_query_set()
return qs._clone(klass=queryset_cls)
def __reduce__(self):
# our pickling support breaks for subclasses (e.g. RelatedManager)

View file

@ -208,6 +208,11 @@ class Car(models.Model):
objects = PassThroughManager(DudeQuerySet)
class SpotManager(PassThroughManager):
def get_query_set(self):
return super(SpotManager, self).get_query_set().filter(secret=False)
class SpotQuerySet(models.query.QuerySet):
def closed(self):
return self.filter(closed=True)
@ -220,9 +225,10 @@ class Spot(models.Model):
name = models.CharField(max_length=20)
secure = models.BooleanField(default=True)
closed = models.BooleanField(default=False)
secret = models.BooleanField(default=False)
owner = models.ForeignKey(Dude, related_name='spots_owned')
objects = PassThroughManager.for_queryset_class(SpotQuerySet)()
objects = SpotManager.for_queryset_class(SpotQuerySet)()
class Tracked(models.Model):

View file

@ -646,17 +646,28 @@ class CreatePassThroughManagerTests(TestCase):
def test_reverse_manager(self):
Spot.objects.create(
name='The Crib', owner=self.dude, closed=True, secure=True)
name='The Crib', owner=self.dude, closed=True, secure=True,
secret=False)
self.assertEqual(self.dude.spots_owned.closed().count(), 1)
def test_related_queryset_pickling(self):
Spot.objects.create(
name='The Crib', owner=self.dude, closed=True, secure=True)
name='The Crib', owner=self.dude, closed=True, secure=True,
secret=False)
qs = self.dude.spots_owned.closed()
pickled_qs = pickle.dumps(qs)
unpickled_qs = pickle.loads(pickled_qs)
self.assertEqual(unpickled_qs.secured().count(), 1)
def test_related_queryset_superclass_method(self):
Spot.objects.create(
name='The Crib', owner=self.dude, closed=True, secure=True,
secret=False)
Spot.objects.create(
name='The Secret Crib', owner=self.dude, closed=False, secure=True,
secret=True)
self.assertEqual(self.dude.spots_owned.count(), 1)
def test_related_manager_create(self):
self.dude.spots_owned.create(name='The Crib', closed=True, secure=True)