Add helper function for django-guardian.

This commit is contained in:
Ben Konrath
2016-09-01 12:15:21 +02:00
parent 8811c177bd
commit c695029cfa
4 changed files with 65 additions and 0 deletions
View File
+35
View File
@@ -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
+21
View File
@@ -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()
@@ -1189,6 +1191,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):
@@ -1210,6 +1230,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