Raise exception instead of cause `TypeError` when `polymorphic_ctype_id` is invalid.

fix_request_path_info
Mark Walker 2018-11-22 20:05:57 +00:00
parent 6d27bb3334
commit fd9d0fa2b8
3 changed files with 22 additions and 10 deletions

View File

@ -107,12 +107,14 @@ class PolymorphicModel(six.with_metaclass(PolymorphicModelBase, models.Model)):
# Protect against bad imports (dumpdata without --natural) or other # Protect against bad imports (dumpdata without --natural) or other
# issues missing with the ContentType models. # issues missing with the ContentType models.
if model is not None \ if model is not None and not issubclass(model, self.__class__):
and not issubclass(model, self.__class__) \ if self.__class__._meta.proxy_for_model is None or \
and not issubclass(model, self.__class__._meta.proxy_for_model): 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, raise PolymorphicTypeInvalid("ContentType {0} for {1} #{2} does not point to a subclass!".format(
)) self.polymorphic_ctype_id, model, self.pk,
))
return model return model
def get_real_concrete_instance_class_id(self): def get_real_concrete_instance_class_id(self):

View File

@ -218,7 +218,7 @@ class ChildModelWithManager(PolymorphicModel):
class PlainMyManagerQuerySet(QuerySet): class PlainMyManagerQuerySet(QuerySet):
def my_queryset_foo(self): 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): class PlainMyManager(models.Manager):

View File

@ -4,12 +4,12 @@ import uuid
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.db import models from django.db import models
from django.db.models import Case, Count, Q, When 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 django.utils import six
from polymorphic import query_translate from polymorphic import query_translate
from polymorphic.managers import PolymorphicManager from polymorphic.managers import PolymorphicManager
from polymorphic.models import PolymorphicTypeUndefined from polymorphic.models import PolymorphicTypeInvalid, PolymorphicTypeUndefined
from polymorphic.tests.models import ( from polymorphic.tests.models import (
ArtProject, ArtProject,
Base, Base,
@ -68,7 +68,6 @@ from polymorphic.tests.models import (
ProxyModelA, ProxyModelA,
ProxyModelB, ProxyModelB,
ProxyModelBase, ProxyModelBase,
QuerySet,
RedheadDuck, RedheadDuck,
RelationA, RelationA,
RelationB, RelationB,
@ -967,6 +966,17 @@ class PolymorphicTests(TransactionTestCase):
with self.assertRaises(PolymorphicTypeUndefined): with self.assertRaises(PolymorphicTypeUndefined):
list(Model2A.objects.all()) 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): def test_bulk_create_abstract_inheritance(self):
ArtProject.objects.bulk_create([ ArtProject.objects.bulk_create([
ArtProject(topic='Painting with Tim', artist='T. Turner'), ArtProject(topic='Painting with Tim', artist='T. Turner'),