mirror of
https://github.com/Hopiu/django-model-utils.git
synced 2026-03-16 20:00:23 +00:00
Provide dir() support for PassThroughManagers.
Reported in #55 by erikcw.
This commit is contained in:
parent
b5b5864d5f
commit
8a1d0662f1
3 changed files with 54 additions and 0 deletions
|
|
@ -4,6 +4,12 @@ CHANGES
|
|||
master (unreleased)
|
||||
-------------------
|
||||
|
||||
* ``PassThroughManager`` now has support for seeing exposed methods via
|
||||
``dir``, allowing `IPython`_ tab completion to be useful. Merge of GH-104,
|
||||
fixes GH-55.
|
||||
|
||||
.. _IPython: http://ipython.org/
|
||||
|
||||
|
||||
2.0.3 (2014.03.19)
|
||||
-------------------
|
||||
|
|
|
|||
|
|
@ -244,6 +244,20 @@ class PassThroughManagerMixin(object):
|
|||
return getattr(self.get_query_set(), name)
|
||||
return getattr(self.get_queryset(), name)
|
||||
|
||||
def __dir__(self):
|
||||
"""
|
||||
Allow introspection via dir() and ipythonesque tab-discovery.
|
||||
|
||||
We do dir(type(self)) because to do dir(self) would be a recursion
|
||||
error.
|
||||
We call dir(self.get_query_set()) because it is possible that the
|
||||
queryset returned by get_query_set() is interesting, even if
|
||||
self._queryset_cls is None.
|
||||
"""
|
||||
my_values = frozenset(dir(type(self)))
|
||||
my_values |= frozenset(dir(self.get_query_set()))
|
||||
return list(my_values)
|
||||
|
||||
def get_queryset(self):
|
||||
try:
|
||||
qs = super(PassThroughManagerMixin, self).get_queryset()
|
||||
|
|
|
|||
|
|
@ -1235,6 +1235,40 @@ class PassThroughManagerTests(TestCase):
|
|||
self.assertFalse(hasattr(dude.cars_owned, 'by_name'))
|
||||
|
||||
|
||||
def test_using_dir(self):
|
||||
# make sure introspecing via dir() doesn't actually cause queries,
|
||||
# just as a sanity check.
|
||||
with self.assertNumQueries(0):
|
||||
querysets_to_dir = (
|
||||
Dude.objects,
|
||||
Dude.objects.by_name('Duder'),
|
||||
Dude.objects.all().by_name('Duder'),
|
||||
Dude.abiders,
|
||||
Dude.abiders.rug_positive(),
|
||||
Dude.abiders.all().rug_positive()
|
||||
)
|
||||
for qs in querysets_to_dir:
|
||||
self.assertTrue('by_name' in dir(qs))
|
||||
self.assertTrue('abiding' in dir(qs))
|
||||
self.assertTrue('rug_positive' in dir(qs))
|
||||
self.assertTrue('rug_negative' in dir(qs))
|
||||
# some standard qs methods
|
||||
self.assertTrue('count' in dir(qs))
|
||||
self.assertTrue('order_by' in dir(qs))
|
||||
self.assertTrue('select_related' in dir(qs))
|
||||
# make sure it's been de-duplicated
|
||||
self.assertEqual(1, dir(qs).count('distinct'))
|
||||
|
||||
# manager only method.
|
||||
self.assertTrue('get_stats' in dir(Dude.abiders))
|
||||
# manager only method shouldn't appear on the non AbidingManager
|
||||
self.assertFalse('get_stats' in dir(Dude.objects))
|
||||
# standard manager methods
|
||||
self.assertTrue('get_query_set' in dir(Dude.abiders))
|
||||
self.assertTrue('contribute_to_class' in dir(Dude.abiders))
|
||||
|
||||
|
||||
|
||||
class CreatePassThroughManagerTests(TestCase):
|
||||
def setUp(self):
|
||||
self.dude = Dude.objects.create(name='El Duderino')
|
||||
|
|
|
|||
Loading…
Reference in a new issue