Provide a better error message when polymorphic_ctype_id is Null

refs #51, #140, #304
fix_request_path_info
Diederik van der Boor 2017-08-01 11:38:36 +02:00
parent b772c06358
commit fb8eed78ad
2 changed files with 23 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

@ -4,6 +4,8 @@ import django
from django.db.models import Case, Count, Q, When
from django.test import TestCase
from django.utils import six
from polymorphic.models import PolymorphicTypeUndefined
from polymorphic.tests import * # all models
@ -765,6 +767,16 @@ class PolymorphicTests(TestCase):
result = Model2B.objects.annotate(val=Concat('field1', 'field2'))
self.assertEqual(list(result), [])
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):
"""