[Python-modules-commits] [python-django-mptt] 04/06: django-1.10 Prepare the manager-using code for Django 1.10
Thomas Goirand
zigo at moszumanska.debian.org
Fri Aug 5 09:20:44 UTC 2016
This is an automated email from the git hooks/post-receive script.
zigo pushed a commit to branch master
in repository python-django-mptt.
commit 53f25a8b35fbec95b19adcb00d083d2269f9dcec
Author: Thomas Goirand <zigo at debian.org>
Date: Fri Aug 5 09:16:07 2016 +0000
django-1.10 Prepare the manager-using code for Django 1.10
This change simply requires the programmer to ensure that
_default_manager returns a tree manager. Custom manager classes
must extend TreeManager.
---
mptt/admin.py | 4 ++--
mptt/forms.py | 2 +-
mptt/managers.py | 18 +++++----------
mptt/models.py | 52 ++++++++----------------------------------
mptt/querysets.py | 4 ++--
mptt/templatetags/mptt_tags.py | 2 +-
mptt/utils.py | 2 +-
tests/myapp/doctests.txt | 20 ++++++++--------
tests/myapp/models.py | 3 ---
tests/myapp/tests.py | 25 ++++----------------
tests/myapp/urls.py | 4 ++--
11 files changed, 40 insertions(+), 96 deletions(-)
diff --git a/mptt/admin.py b/mptt/admin.py
index 730a146..aa4ccb3 100644
--- a/mptt/admin.py
+++ b/mptt/admin.py
@@ -68,7 +68,7 @@ class MPTTModelAdmin(ModelAdmin):
# If this is True, the confirmation page has been displayed
if request.POST.get('post'):
n = 0
- with queryset.model._tree_manager.delay_mptt_updates():
+ with queryset.model._default_manager.delay_mptt_updates():
for obj in queryset:
if self.has_delete_permission(request, obj):
obj.delete()
@@ -218,7 +218,7 @@ class DraggableMPTTAdmin(MPTTModelAdmin):
return http.HttpResponse('FAIL, no permission.')
try:
- self.model._tree_manager.move_node(cut_item, pasted_on, position)
+ self.model._default_manager.move_node(cut_item, pasted_on, position)
except InvalidMove as e:
self.message_user(request, '%s' % e)
return http.HttpResponse('FAIL, invalid move.')
diff --git a/mptt/forms.py b/mptt/forms.py
index ecbf421..e294aee 100644
--- a/mptt/forms.py
+++ b/mptt/forms.py
@@ -121,7 +121,7 @@ class MoveNodeForm(forms.Form):
super(MoveNodeForm, self).__init__(*args, **kwargs)
opts = node._mptt_meta
if valid_targets is None:
- valid_targets = node._tree_manager.exclude(**{
+ valid_targets = node.__class__._default_manager.exclude(**{
opts.tree_id_attr: getattr(node, opts.tree_id_attr),
opts.left_attr + '__gte': getattr(node, opts.left_attr),
opts.right_attr + '__lte': getattr(node, opts.right_attr),
diff --git a/mptt/managers.py b/mptt/managers.py
index a216429..e46df06 100644
--- a/mptt/managers.py
+++ b/mptt/managers.py
@@ -66,6 +66,7 @@ def delegate_manager(method):
"""
@functools.wraps(method)
def wrapped(self, *args, **kwargs):
+ return method(self, *args, **kwargs) # FIXME what should this really do?
if self._base_manager:
return getattr(self._base_manager, method.__name__)(*args, **kwargs)
return method(self, *args, **kwargs)
@@ -78,16 +79,9 @@ class TreeManager(models.Manager.from_queryset(TreeQuerySet)):
A manager for working with trees of objects.
"""
- def contribute_to_class(self, model, name):
- super(TreeManager, self).contribute_to_class(model, name)
-
- if not model._meta.abstract:
- self.tree_model = _get_tree_model(model)
-
- self._base_manager = None
- if self.tree_model is not model:
- # _base_manager is the treemanager on tree_model
- self._base_manager = self.tree_model._tree_manager
+ @property
+ def tree_model(self):
+ return _get_tree_model(self.model)
def get_queryset(self, *args, **kwargs):
"""
@@ -482,7 +476,7 @@ class TreeManager(models.Manager.from_queryset(TreeQuerySet)):
'rel_table': qn(rel_model._meta.db_table),
'mptt_fk': qn(rel_model._meta.get_field(rel_field).column),
'mptt_table': qn(self.tree_model._meta.db_table),
- 'mptt_rel_to': qn(mptt_field.rel.field_name),
+ 'mptt_rel_to': qn(mptt_field.remote_field.field_name),
'tree_id': qn(meta.get_field(self.tree_id_attr).column),
'left': qn(meta.get_field(self.left_attr).column),
'right': qn(meta.get_field(self.right_attr).column),
@@ -492,7 +486,7 @@ class TreeManager(models.Manager.from_queryset(TreeQuerySet)):
'rel_table': qn(rel_model._meta.db_table),
'mptt_fk': qn(rel_model._meta.get_field(rel_field).column),
'mptt_table': qn(self.tree_model._meta.db_table),
- 'mptt_rel_to': qn(mptt_field.rel.field_name),
+ 'mptt_rel_to': qn(mptt_field.remote_field.field_name),
}
return queryset.extra(select={count_attr: subquery})
diff --git a/mptt/models.py b/mptt/models.py
index 1442124..dcf4acd 100644
--- a/mptt/models.py
+++ b/mptt/models.py
@@ -212,7 +212,7 @@ class MPTTOptions(object):
# Fall back on tree id ordering if multiple root nodes have
# the same values.
order_by.append(opts.tree_id_attr)
- queryset = node.__class__._tree_manager.db_manager(node._state.db).filter(filters).order_by(*order_by)
+ queryset = node._tree_manager.db_manager(node._state.db).filter(filters).order_by(*order_by)
if node.pk:
queryset = queryset.exclude(pk=node.pk)
try:
@@ -271,7 +271,7 @@ class MPTTModelBase(ModelBase):
bases = [base for base in cls.mro() if issubclass(base, MPTTModel)]
for base in bases:
if (not (base._meta.abstract or base._meta.proxy) and
- base._tree_manager.tree_model is base):
+ getattr(base._default_manager, 'tree_model', None) is base):
cls._mptt_tracking_base = base
break
if cls is cls._mptt_tracking_base:
@@ -294,8 +294,6 @@ class MPTTModelBase(ModelBase):
if not hasattr(cls, '_mptt_meta'):
cls._mptt_meta = MPTTOptions(**kwargs)
- abstract = getattr(cls._meta, 'abstract', False)
-
try:
MPTTModel
except NameError:
@@ -333,40 +331,6 @@ class MPTTModelBase(ModelBase):
field = models.PositiveIntegerField(db_index=True, editable=False)
field.contribute_to_class(cls, field_name)
- # Add a tree manager, if there isn't one already
- if not abstract:
- manager = getattr(cls, 'objects', None)
- if manager is None:
- manager = cls._default_manager._copy_to_model(cls)
- manager.contribute_to_class(cls, 'objects')
- elif manager.model != cls:
- # manager was inherited
- manager = manager._copy_to_model(cls)
- manager.contribute_to_class(cls, 'objects')
-
- # make sure we have a tree manager somewhere
- tree_manager = None
- if hasattr(cls._meta, 'concrete_managers'): # Django < 1.10
- cls_managers = cls._meta.concrete_managers + cls._meta.abstract_managers
- cls_managers = [r[2] for r in cls_managers]
- else:
- cls_managers = cls._meta.managers
-
- for cls_manager in cls_managers:
- if isinstance(cls_manager, TreeManager):
- # prefer any locally defined manager (i.e. keep going if not local)
- if cls_manager.model is cls:
- tree_manager = cls_manager
- break
-
- if tree_manager and tree_manager.model is not cls:
- tree_manager = tree_manager._copy_to_model(cls)
- elif tree_manager is None:
- tree_manager = TreeManager()
- tree_manager.contribute_to_class(cls, '_tree_manager')
-
- # avoid using ManagerDescriptor, so instances can refer to self._tree_manager
- setattr(cls, '_tree_manager', tree_manager)
return cls
@@ -386,7 +350,8 @@ class MPTTModel(six.with_metaclass(MPTTModelBase, models.Model)):
"""
Base class for tree models.
"""
- _default_manager = TreeManager()
+
+ objects = TreeManager()
class Meta:
abstract = True
@@ -394,7 +359,10 @@ class MPTTModel(six.with_metaclass(MPTTModelBase, models.Model)):
def __init__(self, *args, **kwargs):
super(MPTTModel, self).__init__(*args, **kwargs)
self._mptt_meta.update_mptt_cached_fields(self)
- self._tree_manager = self._tree_manager.db_manager(self._state.db)
+
+ @property
+ def _tree_manager(self):
+ return _get_tree_model(self.__class__)._default_manager
def _mpttfield(self, fieldname):
translated_fieldname = getattr(self._mptt_meta, fieldname + '_attr')
@@ -789,7 +757,7 @@ class MPTTModel(six.with_metaclass(MPTTModelBase, models.Model)):
if not self.pk or self._mpttfield('tree_id') is None:
return False
opts = self._meta
- if opts.pk.rel is None:
+ if opts.pk.remote_field is None:
return True
else:
if not hasattr(self, '_mptt_saved'):
@@ -1031,7 +999,7 @@ class MPTTModel(six.with_metaclass(MPTTModelBase, models.Model)):
def _mptt_refresh(self):
if not self.pk:
return
- manager = type(self)._tree_manager
+ manager = type(self)._default_manager
opts = self._mptt_meta
values = manager.filter(pk=self.pk).values(
opts.left_attr,
diff --git a/mptt/querysets.py b/mptt/querysets.py
index dcad16a..cc72d4e 100644
--- a/mptt/querysets.py
+++ b/mptt/querysets.py
@@ -8,14 +8,14 @@ class TreeQuerySet(models.query.QuerySet):
"""
Alias to `mptt.managers.TreeManager.get_queryset_descendants`.
"""
- return self.model._tree_manager.get_queryset_descendants(self, *args, **kwargs)
+ return self.model._default_manager.get_queryset_descendants(self, *args, **kwargs)
get_descendants.queryset_only = True
def get_ancestors(self, *args, **kwargs):
"""
Alias to `mptt.managers.TreeManager.get_queryset_ancestors`.
"""
- return self.model._tree_manager.get_queryset_ancestors(self, *args, **kwargs)
+ return self.model._default_manager.get_queryset_ancestors(self, *args, **kwargs)
get_ancestors.queryset_only = True
def get_cached_trees(self):
diff --git a/mptt/templatetags/mptt_tags.py b/mptt/templatetags/mptt_tags.py
index 8af257d..ff4f055 100644
--- a/mptt/templatetags/mptt_tags.py
+++ b/mptt/templatetags/mptt_tags.py
@@ -30,7 +30,7 @@ class FullTreeForModelNode(template.Node):
raise template.TemplateSyntaxError(
_('full_tree_for_model tag was given an invalid model: %s') % self.model
)
- context[self.context_var] = cls._tree_manager.all()
+ context[self.context_var] = cls._default_manager.all()
return ''
diff --git a/mptt/utils.py b/mptt/utils.py
index 49e4779..c0ae9dc 100644
--- a/mptt/utils.py
+++ b/mptt/utils.py
@@ -144,7 +144,7 @@ def drilldown_tree_for_node(node, rel_cls=None, rel_field=None, count_attr=None,
descendants, otherwise it will be for each child itself.
"""
if rel_cls and rel_field and count_attr:
- children = node._tree_manager.add_related_count(
+ children = node.__class__._default_manager.add_related_count(
node.get_children(), rel_cls, rel_field, count_attr, cumulative)
else:
children = node.get_children()
diff --git a/tests/myapp/doctests.txt b/tests/myapp/doctests.txt
index 607331e..97c7743 100644
--- a/tests/myapp/doctests.txt
+++ b/tests/myapp/doctests.txt
@@ -208,23 +208,23 @@
# TreeManager Methods #########################################################
# check that tree manager is the explicitly defined tree manager for Person
->>> Person._tree_manager == Person.objects
+>>> Person._default_manager == Person.objects
True
-# managers of non-abstract bases don't get inherited, so:
->>> Student._tree_manager == Student.objects
-False
+# managers of non-abstract bases get inherited, so:
+>>> Student._default_manager == Student.objects
+True
->>> Student._tree_manager == Person._tree_manager
-False
+>>> Student._default_manager == Person._default_manager
+True
->>> Student._tree_manager.model
+>>> Student._default_manager.model
<class 'myapp.models.Student'>
->>> Student._tree_manager.tree_model
+>>> Student._default_manager.tree_model
<class 'myapp.models.Person'>
->>> Person._tree_manager.model
+>>> Person._default_manager.model
<class 'myapp.models.Person'>
->>> Person._tree_manager.tree_model
+>>> Person._default_manager.tree_model
<class 'myapp.models.Person'>
>>> Genre.objects.root_node(action.tree_id)
diff --git a/tests/myapp/models.py b/tests/myapp/models.py
index d86c1e5..756eeb7 100644
--- a/tests/myapp/models.py
+++ b/tests/myapp/models.py
@@ -164,9 +164,6 @@ class Person(MPTTModel):
# just testing it's actually possible to override the tree manager
objects = CustomTreeManager()
- # This line is set because of https://github.com/django-mptt/django-mptt/issues/369
- _default_manager = objects
-
def __str__(self):
return self.name
diff --git a/tests/myapp/tests.py b/tests/myapp/tests.py
index 0a2ad8a..49dd700 100644
--- a/tests/myapp/tests.py
+++ b/tests/myapp/tests.py
@@ -9,7 +9,7 @@ import unittest
from django import forms
from django.contrib.auth.models import Group, User
-from django.db.models import Q
+from django.db.models import Q, Manager
from django.db.models.query_utils import DeferredAttribute
from django.apps import apps
from django.forms.models import modelform_factory
@@ -1151,7 +1151,7 @@ class ManagerTests(TreeTestCase):
for model in apps.get_models():
if not issubclass(model, MPTTModel):
continue
- tm = model._tree_manager
+ tm = model._default_manager
if id(tm) in seen:
self.fail(
"Tree managers for %s and %s are the same manager"
@@ -1163,27 +1163,12 @@ class ManagerTests(TreeTestCase):
for model in apps.get_models():
if not issubclass(model, MPTTModel):
continue
- self.assertEqual(model._tree_manager.model, model)
-
- def test_base_manager_infinite_recursion(self):
- # repeatedly calling _base_manager should eventually return None
- for model in apps.get_models():
- if not issubclass(model, MPTTModel):
- continue
- manager = model._tree_manager
- for i in range(20):
- manager = manager._base_manager
- if manager is None:
- break
- else:
- self.fail("Detected infinite recursion in %s._tree_manager._base_manager" % model)
+ self.assertEqual(model._default_manager.model, model)
def test_proxy_custom_manager(self):
- self.assertIsInstance(SingleProxyModel._tree_manager, CustomTreeManager)
- self.assertIsInstance(SingleProxyModel._tree_manager._base_manager, TreeManager)
-
+ self.assertIsInstance(SingleProxyModel._default_manager, CustomTreeManager)
self.assertIsInstance(SingleProxyModel.objects, CustomTreeManager)
- self.assertIsInstance(SingleProxyModel.objects._base_manager, TreeManager)
+ self.assertIsInstance(SingleProxyModel._base_manager, Manager)
def test_get_queryset_descendants(self):
def get_desc_names(qs, include_self=False):
diff --git a/tests/myapp/urls.py b/tests/myapp/urls.py
index 5f2b4a4..a0d606d 100644
--- a/tests/myapp/urls.py
+++ b/tests/myapp/urls.py
@@ -1,4 +1,4 @@
-from django.conf.urls import include, url
+from django.conf.urls import url
from django.contrib import admin
@@ -7,5 +7,5 @@ admin.autodiscover()
urlpatterns = [
- url(r'^admin/', include(admin.site.urls)),
+ url(r'^admin/', admin.site.urls),
]
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-django-mptt.git
More information about the Python-modules-commits
mailing list