diff --git a/polymorphic/models.py b/polymorphic/models.py index 0b2cb92..e2bb0a2 100644 --- a/polymorphic/models.py +++ b/polymorphic/models.py @@ -107,12 +107,14 @@ class PolymorphicModel(six.with_metaclass(PolymorphicModelBase, models.Model)): # Protect against bad imports (dumpdata without --natural) or other # issues missing with the ContentType models. - if model is not None \ - and not issubclass(model, self.__class__) \ - and not issubclass(model, self.__class__._meta.proxy_for_model): - raise PolymorphicTypeInvalid("ContentType {0} for {1} #{2} does not point to a subclass!".format( - self.polymorphic_ctype_id, model, self.pk, - )) + if model is not None and not issubclass(model, self.__class__): + if self.__class__._meta.proxy_for_model is None or \ + not issubclass(model, self.__class__._meta.proxy_for_model): + + raise PolymorphicTypeInvalid("ContentType {0} for {1} #{2} does not point to a subclass!".format( + self.polymorphic_ctype_id, model, self.pk, + )) + return model def get_real_concrete_instance_class_id(self): diff --git a/polymorphic/tests/models.py b/polymorphic/tests/models.py index 2ea89d5..c74ae1e 100644 --- a/polymorphic/tests/models.py +++ b/polymorphic/tests/models.py @@ -218,7 +218,7 @@ class ChildModelWithManager(PolymorphicModel): class PlainMyManagerQuerySet(QuerySet): def my_queryset_foo(self): - return self.all() # Just a method to prove the existance of the custom queryset. + return self.all() # Just a method to prove the existence of the custom queryset. class PlainMyManager(models.Manager): diff --git a/polymorphic/tests/test_orm.py b/polymorphic/tests/test_orm.py index 557e370..3c70e28 100644 --- a/polymorphic/tests/test_orm.py +++ b/polymorphic/tests/test_orm.py @@ -4,12 +4,12 @@ import uuid from django.contrib.contenttypes.models import ContentType from django.db import models from django.db.models import Case, Count, Q, When -from django.test import TestCase, TransactionTestCase +from django.test import TransactionTestCase from django.utils import six from polymorphic import query_translate from polymorphic.managers import PolymorphicManager -from polymorphic.models import PolymorphicTypeUndefined +from polymorphic.models import PolymorphicTypeInvalid, PolymorphicTypeUndefined from polymorphic.tests.models import ( ArtProject, Base, @@ -68,7 +68,6 @@ from polymorphic.tests.models import ( ProxyModelA, ProxyModelB, ProxyModelBase, - QuerySet, RedheadDuck, RelationA, RelationB, @@ -975,6 +974,17 @@ class PolymorphicTests(TransactionTestCase): with self.assertRaises(PolymorphicTypeUndefined): list(Model2A.objects.all()) + def test_invalid_polymorphic_id(self): + """Test that a proper error message is displayed when the database ``polymorphic_ctype_id`` is invalid""" + Model2A.objects.create(field1='A1') + Model2B.objects.create(field1='A1', field2='B2') + Model2B.objects.create(field1='A1', field2='B2') + invalid = ContentType.objects.get_for_model(PlainA).pk + Model2A.objects.all().update(polymorphic_ctype_id=invalid) + + with self.assertRaises(PolymorphicTypeInvalid): + list(Model2A.objects.all()) + def test_bulk_create_abstract_inheritance(self): ArtProject.objects.bulk_create([ ArtProject(topic='Painting with Tim', artist='T. Turner'),