[Python-modules-commits] [django-polymorphic] 01/06: Import django-polymorphic_1.0.2.orig.tar.gz

Michael Fladischer fladi at moszumanska.debian.org
Mon Oct 17 07:46:17 UTC 2016


This is an automated email from the git hooks/post-receive script.

fladi pushed a commit to branch master
in repository django-polymorphic.

commit 698c35df35f1bc7e3123674abf62a67f3e6ea81c
Author: Michael Fladischer <FladischerMichael at fladi.at>
Date:   Mon Oct 17 09:30:07 2016 +0200

    Import django-polymorphic_1.0.2.orig.tar.gz
---
 README.rst                                         | 13 ++++++--
 docs/changelog.rst                                 | 14 +++++++++
 docs/conf.py                                       |  4 +--
 docs/quickstart.rst                                |  2 +-
 docs/third-party.rst                               | 17 +++++++++++
 polymorphic/__init__.py                            |  2 +-
 polymorphic/admin/childadmin.py                    | 15 ++++++++++
 polymorphic/base.py                                |  5 +++-
 polymorphic/contrib/__init__.py                    |  0
 polymorphic/contrib/guardian.py                    | 35 ++++++++++++++++++++++
 polymorphic/formsets/models.py                     |  7 ++---
 .../static/polymorphic/css/polymorphic_inlines.css |  1 +
 polymorphic/tests.py                               | 21 +++++++++++++
 13 files changed, 125 insertions(+), 11 deletions(-)

diff --git a/README.rst b/README.rst
index 52f52af..4c769cf 100644
--- a/README.rst
+++ b/README.rst
@@ -1,7 +1,7 @@
 .. image::  https://travis-ci.org/django-polymorphic/django-polymorphic.png?branch=master
     :target: http://travis-ci.org/django-polymorphic/django-polymorphic
-.. image:: https://img.shields.io/pypi/v/django-polymorphic-tree.svg
-    :target: https://pypi.python.org/pypi/django-polymorphic-tree/
+.. image:: https://img.shields.io/pypi/v/django-polymorphic.svg
+    :target: https://pypi.python.org/pypi/django-polymorphic/
 .. image:: https://img.shields.io/codecov/c/github/django-polymorphic/django-polymorphic/master.svg
     :target: https://codecov.io/github/django-polymorphic/django-polymorphic?branch=master
 
@@ -63,6 +63,15 @@ That's what this library is designed for!
 
 For more information, see the `documentation at Read the Docs <https://django-polymorphic.readthedocs.io/>`_.
 
+Installation
+------------
+
+Install using ``pip``\ ...
+
+.. code:: bash
+
+    $ pip install django-polymorphic
+
 License
 =======
 
diff --git a/docs/changelog.rst b/docs/changelog.rst
index e3d38a3..3092a46 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -1,6 +1,18 @@
 Changelog
 =========
 
+Version 1.0.2 (2016-10-14)
+--------------------------
+
+* Added helper function for django-guardian_; add
+  ``GUARDIAN_GET_CONTENT_TYPE = 'polymorphic.contrib.guardian.get_polymorphic_base_content_type'``
+  to the project settings to let guardian handles inherited models properly.
+* Fixed ``polymorphic_modelformset_factory()`` usage.
+* Fixed Python 3 bug for inline formsets.
+* Fixed CSS for Grappelli, so model choice menu properly overlaps.
+* Fixed ``ParentAdminNotRegistered`` exception for models that are registered via a proxy model instead of the real base model.
+
+
 Version 1.0.1 (2016-09-11)
 --------------------------
 
@@ -65,6 +77,7 @@ Version 0.9 (2016-02-17)
 * Fix Django 1.9 handling of custom URLs.
   The new change-URL redirect overlapped any custom URLs defined in the child admin.
 * Fix Django 1.9 support in the admin.
+* Fix setting an extra custom manager without overriding the ``_default_manager``.
 * Fix missing ``history_view()`` redirection to the child admin, which is important for django-reversion_ support.
   See the documentation for hints for :ref:`django-reversion-compare support <django-reversion-compare-support>`.
 
@@ -255,6 +268,7 @@ It supports Django 1.1 up till 1.4 and Python 2.4 up till 2.7.
 For a detailed list of it's changes, see the :doc:`archived changelog <changelog_archive>`.
 
 .. _Grappelli: http://grappelliproject.com/
+.. _django-guardian: https://github.com/django-guardian/django-guardian
 .. _django-parler: https://github.com/django-parler/django-parler
 .. _django-reversion: https://github.com/etianen/django-reversion
 .. _django-reversion-compare: https://github.com/jedie/django-reversion-compare
diff --git a/docs/conf.py b/docs/conf.py
index 6bada59..f14fa5f 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -55,9 +55,9 @@ copyright = u'2013, Bert Constantin, Chris Glass, Diederik van der Boor'
 # built documents.
 #
 # The short X.Y version.
-version = '1.0'
+version = '1.0.2'
 # The full version, including alpha/beta/rc tags.
-release = '1.0'
+release = '1.0.2'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/docs/quickstart.rst b/docs/quickstart.rst
index f14c816..254918a 100644
--- a/docs/quickstart.rst
+++ b/docs/quickstart.rst
@@ -12,7 +12,7 @@ Update the settings file::
         'django.contrib.contenttypes',
     )
 
-The current release of *django-polymorphic* supports Django 1.4 till 1.9 and Python 3 is supported.
+The current release of *django-polymorphic* supports Django 1.4 till 1.10 and Python 3 is supported.
 
 Making Your Models Polymorphic
 ------------------------------
diff --git a/docs/third-party.rst b/docs/third-party.rst
index 7b274f5..837f21f 100644
--- a/docs/third-party.rst
+++ b/docs/third-party.rst
@@ -97,7 +97,24 @@ This doesn't work, since it needs to look for revisions of the child model. Usin
 the view of the actual child model is used, similar to the way the regular change and delete views are redirected.
 
 
+django-guardian support
+-----------------------
+
+.. versionadded:: 1.0.2
+
+You can configure django-guardian_ to use the base model for object level permissions.
+Add this option to your settings:
+
+.. code-block:: python
+
+    GUARDIAN_GET_CONTENT_TYPE = 'polymorphic.contrib.guardian.get_polymorphic_base_content_type'
+
+This option requires django-guardian_ >= 1.4.6. Details about how this option works are available in the
+`django-guardian documentation <https://django-guardian.readthedocs.io/en/latest/configuration.html#guardian-get-content-type>`_.
+
+
 .. _django-reversion: https://github.com/etianen/django-reversion
 .. _django-reversion-compare: https://github.com/jedie/django-reversion-compare
 .. _django-mptt: https://github.com/django-mptt/django-mptt
 .. _django-polymorphic-tree: https://github.com/django-polymorphic/django-polymorphic-tree
+.. _django-guardian: https://github.com/django-guardian/django-guardian
diff --git a/polymorphic/__init__.py b/polymorphic/__init__.py
index 1e85e95..4b8c380 100644
--- a/polymorphic/__init__.py
+++ b/polymorphic/__init__.py
@@ -7,7 +7,7 @@ This code and affiliated files are (C) by Bert Constantin and individual contrib
 Please see LICENSE and AUTHORS for more information.
 """
 # See PEP 440 (https://www.python.org/dev/peps/pep-0440/)
-__version__ = "1.0.1"
+__version__ = "1.0.2"
 
 
 # Monkey-patch Django < 1.5 to allow ContentTypes for proxy models.
diff --git a/polymorphic/admin/childadmin.py b/polymorphic/admin/childadmin.py
index c6ce41c..0d45f88 100644
--- a/polymorphic/admin/childadmin.py
+++ b/polymorphic/admin/childadmin.py
@@ -1,12 +1,15 @@
 """
 The child admin displays the change/delete view of the subclass model.
 """
+import inspect
+
 from django.contrib import admin
 from django.core.urlresolvers import resolve
 from django.utils import six
 from django.utils.translation import ugettext_lazy as _
 
 from .helpers import PolymorphicInlineSupportMixin
+from ..admin import PolymorphicParentModelAdmin
 
 
 class ParentAdminNotRegistered(RuntimeError):
@@ -123,6 +126,18 @@ class PolymorphicChildModelAdmin(admin.ModelAdmin):
         try:
             return self.admin_site._registry[parent_model]
         except KeyError:
+            # Admin is not registered for polymorphic_ctype model, but perhaps it's registered
+            # for a intermediate proxy model, between the parent_model and this model.
+            for klass in inspect.getmro(self.model):
+                if not issubclass(klass, parent_model):
+                    continue  # e.g. found a mixin.
+
+                # Fetch admin instance for model class, see if it's a possible candidate.
+                model_admin = self.admin_site._registry.get(klass)
+                if model_admin is not None and isinstance(model_admin, PolymorphicParentModelAdmin):
+                    return model_admin  # Success!
+
+            # If we get this far without returning there is no admin available
             raise ParentAdminNotRegistered("No parent admin was registered for a '{0}' model.".format(parent_model))
 
     def response_post_save_add(self, request, obj):
diff --git a/polymorphic/base.py b/polymorphic/base.py
index 3405ba5..c42ce89 100644
--- a/polymorphic/base.py
+++ b/polymorphic/base.py
@@ -4,6 +4,7 @@
 """
 from __future__ import absolute_import
 
+import os
 import sys
 import inspect
 
@@ -19,6 +20,8 @@ from .query import PolymorphicQuerySet
 # These are forbidden as field names (a descriptive exception is raised)
 POLYMORPHIC_SPECIAL_Q_KWORDS = ['instance_of', 'not_instance_of']
 
+DUMPDATA_COMMAND = os.path.join('django', 'core', 'management', 'commands', 'dumpdata.py')
+
 try:
     from django.db.models.manager import AbstractManagerDescriptor  # Django 1.5
 except ImportError:
@@ -244,7 +247,7 @@ class PolymorphicModelBase(ModelBase):
         def __getattribute__(self, name):
             if name == '_default_manager':
                 frm = inspect.stack()[1]  # frm[1] is caller file name, frm[3] is caller function name
-                if 'django/core/management/commands/dumpdata.py' in frm[1]:
+                if DUMPDATA_COMMAND in frm[1]:
                     return self.base_objects
                 # caller_mod_name = inspect.getmodule(frm[0]).__name__  # does not work with python 2.4
                 # if caller_mod_name == 'django.core.management.commands.dumpdata':
diff --git a/polymorphic/contrib/__init__.py b/polymorphic/contrib/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/polymorphic/contrib/guardian.py b/polymorphic/contrib/guardian.py
new file mode 100644
index 0000000..55b1601
--- /dev/null
+++ b/polymorphic/contrib/guardian.py
@@ -0,0 +1,35 @@
+from django.contrib.contenttypes.models import ContentType
+
+
+def get_polymorphic_base_content_type(obj):
+    """
+    Helper function to return the base polymorphic content type id. This should used with django-guardian and the
+    GUARDIAN_GET_CONTENT_TYPE option.
+
+    See the django-guardian documentation for more information:
+
+    https://django-guardian.readthedocs.io/en/latest/configuration.html#guardian-get-content-type
+    """
+    if hasattr(obj, 'polymorphic_model_marker'):
+        try:
+            superclasses = list(obj.__class__.mro())
+        except TypeError:
+            # obj is an object so mro() need to be called with the obj.
+            superclasses = list(obj.__class__.mro(obj))
+
+        polymorphic_superclasses = list()
+        for sclass in superclasses:
+            if hasattr(sclass, 'polymorphic_model_marker'):
+                polymorphic_superclasses.append(sclass)
+
+        # PolymorphicMPTT adds an additional class between polymorphic and base class.
+        if hasattr(obj, 'can_have_children'):
+            root_polymorphic_class = polymorphic_superclasses[-3]
+        else:
+            root_polymorphic_class = polymorphic_superclasses[-2]
+        ctype = ContentType.objects.get_for_model(root_polymorphic_class)
+
+    else:
+        ctype = ContentType.objects.get_for_model(obj)
+
+    return ctype
diff --git a/polymorphic/formsets/models.py b/polymorphic/formsets/models.py
index e402b4a..a5e4031 100644
--- a/polymorphic/formsets/models.py
+++ b/polymorphic/formsets/models.py
@@ -180,7 +180,7 @@ class BasePolymorphicModelFormSet(BaseModelFormSet):
                 # Extra forms, cycle between all types
                 # TODO: take the 'extra' value of each child formset into account.
                 total_known = len(self.queryset_data)
-                child_models = self.child_forms.keys()
+                child_models = list(self.child_forms.keys())
                 model = child_models[(i - total_known) % len(child_models)]
 
         form_class = self.get_form_class(model)
@@ -248,7 +248,7 @@ class BasePolymorphicModelFormSet(BaseModelFormSet):
 
 
 def polymorphic_modelformset_factory(model, formset_children,
-                                     formset=BasePolymorphicModelFormSet, fk_name=None,
+                                     formset=BasePolymorphicModelFormSet,
                                      # Base field
                                      # TODO: should these fields be removed in favor of creating
                                      # the base form as a formset child too?
@@ -274,7 +274,6 @@ def polymorphic_modelformset_factory(model, formset_children,
         'form': form,
         'formfield_callback': formfield_callback,
         'formset': formset,
-        'fk_name': fk_name,
         'extra': extra,
         'can_delete': can_delete,
         'can_order': can_order,
@@ -307,7 +306,7 @@ class BasePolymorphicInlineFormSet(BaseInlineFormSet, BasePolymorphicModelFormSe
     """
     Polymorphic formset variation for inline formsets
     """
-    
+
     def _construct_form(self, i, **kwargs):
         return super(BasePolymorphicInlineFormSet, self)._construct_form(i, **kwargs)
 
diff --git a/polymorphic/static/polymorphic/css/polymorphic_inlines.css b/polymorphic/static/polymorphic/css/polymorphic_inlines.css
index c342d37..a4ad938 100644
--- a/polymorphic/static/polymorphic/css/polymorphic_inlines.css
+++ b/polymorphic/static/polymorphic/css/polymorphic_inlines.css
@@ -1,5 +1,6 @@
 .polymorphic-add-choice {
   position: relative;
+  clear: left;
 }
 
 .polymorphic-add-choice a:focus {
diff --git a/polymorphic/tests.py b/polymorphic/tests.py
index d048313..9c2cb3d 100644
--- a/polymorphic/tests.py
+++ b/polymorphic/tests.py
@@ -21,6 +21,7 @@ from django.db import models
 from django.contrib.contenttypes.models import ContentType
 from django.utils import six
 
+from polymorphic.contrib.guardian import get_polymorphic_base_content_type
 from polymorphic.models import PolymorphicModel
 from polymorphic.managers import PolymorphicManager
 from polymorphic.query import PolymorphicQuerySet
@@ -195,6 +196,7 @@ class ModelWithMyManagerNoDefault(ShowFieldTypeAndContent, Model2A):
     my_objects = MyManager()
     field4 = models.CharField(max_length=10)
 
+
 class ModelWithMyManagerDefault(ShowFieldTypeAndContent, Model2A):
     my_objects = MyManager()
     objects = PolymorphicManager()
@@ -1194,6 +1196,24 @@ class PolymorphicTests(TestCase):
         result = Model2B.objects.annotate(val=Concat('field1', 'field2'))
         self.assertEqual(list(result), [])
 
+    def test_contrib_guardian(self):
+        # Regular Django inheritance should return the child model content type.
+        obj = PlainC()
+        ctype = get_polymorphic_base_content_type(obj)
+        self.assertEqual(ctype.name, 'plain c')
+
+        ctype = get_polymorphic_base_content_type(PlainC)
+        self.assertEqual(ctype.name, 'plain c')
+
+        # Polymorphic inheritance should return the parent model content type.
+        obj = Model2D()
+        ctype = get_polymorphic_base_content_type(obj)
+        self.assertEqual(ctype.name, 'model2a')
+
+        ctype = get_polymorphic_base_content_type(Model2D)
+        self.assertEqual(ctype.name, 'model2a')
+
+
 class RegressionTests(TestCase):
 
     def test_for_query_result_incomplete_with_inheritance(self):
@@ -1215,6 +1235,7 @@ class RegressionTests(TestCase):
         expected_queryset = [bottom]
         self.assertQuerysetEqual(Bottom.objects.all(), [repr(r) for r in expected_queryset])
 
+
 class MultipleDatabasesTests(TestCase):
     multi_db = True
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/django-polymorphic.git



More information about the Python-modules-commits mailing list