Add UnsupportedChildType error for formsets

This also replaces the PolymorphicInlineModelAdmin.get_get_child_inline_instance()
and BasePolymorphicModelFormSet._construct_form() lookup with UnsupportedChildType
fix_request_path_info
Diederik van der Boor 2017-10-08 21:53:12 +02:00
parent 4d5fb4be3b
commit cafaf95f06
3 changed files with 25 additions and 4 deletions

View File

@ -10,7 +10,8 @@ from django.contrib.admin.utils import flatten_fieldsets
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.forms import Media from django.forms import Media
from polymorphic.formsets import polymorphic_child_forms_factory, BasePolymorphicInlineFormSet, PolymorphicFormSetChild from polymorphic.formsets import polymorphic_child_forms_factory, BasePolymorphicInlineFormSet, \
PolymorphicFormSetChild, UnsupportedChildType
from polymorphic.formsets.utils import add_media from polymorphic.formsets.utils import add_media
from .helpers import PolymorphicInlineSupportMixin from .helpers import PolymorphicInlineSupportMixin
@ -89,7 +90,7 @@ class PolymorphicInlineModelAdmin(InlineModelAdmin):
try: try:
return self._child_inlines_lookup[model] return self._child_inlines_lookup[model]
except KeyError: except KeyError:
raise ValueError("Model '{0}' not found in child_inlines".format(model.__name__)) raise UnsupportedChildType("Model '{0}' not found in child_inlines".format(model.__name__))
def get_formset(self, request, obj=None, **kwargs): def get_formset(self, request, obj=None, **kwargs):
""" """

View File

@ -12,6 +12,7 @@ from .models import (
BasePolymorphicModelFormSet, BasePolymorphicModelFormSet,
BasePolymorphicInlineFormSet, BasePolymorphicInlineFormSet,
PolymorphicFormSetChild, PolymorphicFormSetChild,
UnsupportedChildType,
polymorphic_modelformset_factory, polymorphic_modelformset_factory,
polymorphic_inlineformset_factory, polymorphic_inlineformset_factory,
polymorphic_child_forms_factory, polymorphic_child_forms_factory,
@ -27,6 +28,7 @@ __all__ = (
'BasePolymorphicModelFormSet', 'BasePolymorphicModelFormSet',
'BasePolymorphicInlineFormSet', 'BasePolymorphicInlineFormSet',
'PolymorphicFormSetChild', 'PolymorphicFormSetChild',
'UnsupportedChildType',
'polymorphic_modelformset_factory', 'polymorphic_modelformset_factory',
'polymorphic_inlineformset_factory', 'polymorphic_inlineformset_factory',
'polymorphic_child_forms_factory', 'polymorphic_child_forms_factory',

View File

@ -5,9 +5,16 @@ from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ImproperlyConfigured, ValidationError from django.core.exceptions import ImproperlyConfigured, ValidationError
from django.forms.models import ModelForm, BaseModelFormSet, BaseInlineFormSet, modelform_factory, modelformset_factory, inlineformset_factory from django.forms.models import ModelForm, BaseModelFormSet, BaseInlineFormSet, modelform_factory, modelformset_factory, inlineformset_factory
from django.utils.functional import cached_property from django.utils.functional import cached_property
from polymorphic.models import PolymorphicModel
from .utils import add_media from .utils import add_media
class UnsupportedChildType(LookupError):
pass
class PolymorphicFormSetChild(object): class PolymorphicFormSetChild(object):
""" """
Metadata to define the inline of a polymorphic child. Metadata to define the inline of a polymorphic child.
@ -167,7 +174,7 @@ class BasePolymorphicModelFormSet(BaseModelFormSet):
model = ContentType.objects.get_for_id(ct_id).model_class() model = ContentType.objects.get_for_id(ct_id).model_class()
if model not in self.child_forms: if model not in self.child_forms:
# Perform basic validation, as we skip the ChoiceField here. # Perform basic validation, as we skip the ChoiceField here.
raise ValidationError("Child model type {0} is not part of the formset".format(model)) raise UnsupportedChildType("Child model type {0} is not part of the formset".format(model))
else: else:
if 'instance' in defaults: if 'instance' in defaults:
model = defaults['instance'].get_real_concrete_instance_class() # respect proxy models model = defaults['instance'].get_real_concrete_instance_class() # respect proxy models
@ -200,7 +207,18 @@ class BasePolymorphicModelFormSet(BaseModelFormSet):
""" """
if not self.child_forms: if not self.child_forms:
raise ImproperlyConfigured("No 'child_forms' defined in {0}".format(self.__class__.__name__)) raise ImproperlyConfigured("No 'child_forms' defined in {0}".format(self.__class__.__name__))
if not issubclass(model, PolymorphicModel):
raise TypeError("Expect polymorphic model type, not {0}".format(model))
try:
return self.child_forms[model] return self.child_forms[model]
except KeyError:
# This may happen when the query returns objects of a type that was not handled by the formset.
raise UnsupportedChildType(
"The '{0}' found a '{1}' model in the queryset, "
"but no form class is registered to display it.".format(
self.__class__.__name__, model.__name__
))
def is_multipart(self): def is_multipart(self):
""" """