[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