From e8d5ce623170ada4c36419eb3bab670aebbd4e67 Mon Sep 17 00:00:00 2001 From: Diederik van der Boor Date: Fri, 4 Apr 2014 15:28:01 +0200 Subject: [PATCH] Add protection against mixed up ContentType tables --- docs/changelog.rst | 1 + polymorphic/polymorphic_model.py | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index b5bcc2b..ead5809 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -7,6 +7,7 @@ Version 0.5.4 (in development) * Fix ``.non_polymorphic()`` to returns a clone of the queryset, instead of effecting the existing queryset. * Fix missing ``alters_data = True`` annotations on the overwritten ``save()`` methods. * Fix infinite recursion bug in the admin with Django 1.6+ +* Added detection of bad ``ContentType`` table data. Version 0.5.3 (2013-09-17) diff --git a/polymorphic/polymorphic_model.py b/polymorphic/polymorphic_model.py index 3f971c2..76b4d51 100644 --- a/polymorphic/polymorphic_model.py +++ b/polymorphic/polymorphic_model.py @@ -103,11 +103,19 @@ class PolymorphicModel(six.with_metaclass(PolymorphicModelBase, models.Model)): # Note that model_class() can return None for stale content types; # when the content type record still exists but no longer refers to an existing model. try: - return ContentType.objects.get_for_id(self.polymorphic_ctype_id).model_class() + model = ContentType.objects.get_for_id(self.polymorphic_ctype_id).model_class() except AttributeError: # Django <1.6 workaround return None + # Protect against bad imports (dumpdata without --natural) or other + # issues missing with the ContentType models. + if not issubclass(model, self.__class__): + raise RuntimeError("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): model_class = self.get_real_instance_class() if model_class is None: