From fd9d0fa2b8a402e36385a4d257ac15d35dda121a Mon Sep 17 00:00:00 2001 From: Mark Walker Date: Thu, 22 Nov 2018 20:05:57 +0000 Subject: [PATCH 1/2] Raise exception instead of cause `TypeError` when `polymorphic_ctype_id` is invalid. --- polymorphic/models.py | 14 ++++++++------ polymorphic/tests/models.py | 2 +- polymorphic/tests/test_orm.py | 16 +++++++++++++--- 3 files changed, 22 insertions(+), 10 deletions(-) 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 82fcfbb..cc8ea4f 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, @@ -967,6 +966,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 lacks the ``polymorphic_ctype_id``""" + 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'), From 3d9ac45cecf6443101ffdd2b19c0f17490131a6e Mon Sep 17 00:00:00 2001 From: Mark Walker Date: Thu, 22 Nov 2018 20:12:48 +0000 Subject: [PATCH 2/2] Correct the docstring for the invalid test. --- polymorphic/tests/test_orm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polymorphic/tests/test_orm.py b/polymorphic/tests/test_orm.py index cc8ea4f..354c02e 100644 --- a/polymorphic/tests/test_orm.py +++ b/polymorphic/tests/test_orm.py @@ -967,7 +967,7 @@ class PolymorphicTests(TransactionTestCase): list(Model2A.objects.all()) def test_invalid_polymorphic_id(self): - """Test that a proper error message is displayed when the database lacks the ``polymorphic_ctype_id``""" + """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')