Provide a better error message when polymorphic_ctype_id is Null

refs #51, #140, #304

(cherry picked from commit fb8eed78ad)
fix_request_path_info
Diederik van der Boor 2017-08-01 11:38:36 +02:00
parent 925c4de34f
commit f126f5f304
2 changed files with 22 additions and 0 deletions

View File

@ -17,6 +17,10 @@ from .query_translate import translate_polymorphic_Q_object
# PolymorphicModel
class PolymorphicTypeUndefined(LookupError):
pass
class PolymorphicModel(six.with_metaclass(PolymorphicModelBase, models.Model)):
"""
Abstract base class that provides polymorphic behaviour
@ -82,6 +86,13 @@ class PolymorphicModel(six.with_metaclass(PolymorphicModelBase, models.Model)):
retrieve objects, then the real class/type of these objects may be
determined using this method.
"""
if self.polymorphic_ctype_id is None:
raise PolymorphicTypeUndefined((
"The model {}#{} does not have a `polymorphic_ctype_id` value defined.\n"
"If you created models outside polymorphic, e.g. through an import or migration, "
"make sure the `polymorphic_ctype_id` field points to the ContentType ID of the model subclass."
).format(self.__class__.__name__, self.pk))
# the following line would be the easiest way to do this, but it produces sql queries
# return self.polymorphic_ctype.model_class()
# so we use the following version, which uses the ContentType manager cache.

View File

@ -5,6 +5,7 @@ from django.db.models import Case, Count, Q, When
from django.test import TestCase
from django.utils import six
from polymorphic.contrib.guardian import get_polymorphic_base_content_type
from polymorphic.models import PolymorphicTypeUndefined
from polymorphic.tests import * # all models
@ -783,6 +784,16 @@ class PolymorphicTests(TestCase):
ctype = get_polymorphic_base_content_type(Model2D)
self.assertEqual(ctype.name, 'model2a')
def test_null_polymorphic_id(self):
"""Test that a proper error message is displayed when the database lacks the ``polymorphic_ctype_id``"""
Model2A.objects.create(field1='A1')
Model2B.objects.create(field1='A1', field2='B2')
Model2B.objects.create(field1='A1', field2='B2')
Model2A.objects.all().update(polymorphic_ctype_id=None)
with self.assertRaises(PolymorphicTypeUndefined):
list(Model2A.objects.all())
def qrepr(data):
"""