Skip to content

Commit cafaf95

Browse files
committed
Add UnsupportedChildType error for formsets
This also replaces the PolymorphicInlineModelAdmin.get_get_child_inline_instance() and BasePolymorphicModelFormSet._construct_form() lookup with UnsupportedChildType
1 parent 4d5fb4b commit cafaf95

File tree

3 files changed

+25
-4
lines changed

3 files changed

+25
-4
lines changed

polymorphic/admin/inlines.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
from django.core.exceptions import ImproperlyConfigured
1111
from django.forms import Media
1212

13-
from polymorphic.formsets import polymorphic_child_forms_factory, BasePolymorphicInlineFormSet, PolymorphicFormSetChild
13+
from polymorphic.formsets import polymorphic_child_forms_factory, BasePolymorphicInlineFormSet, \
14+
PolymorphicFormSetChild, UnsupportedChildType
1415
from polymorphic.formsets.utils import add_media
1516
from .helpers import PolymorphicInlineSupportMixin
1617

@@ -89,7 +90,7 @@ def get_child_inline_instance(self, model):
8990
try:
9091
return self._child_inlines_lookup[model]
9192
except KeyError:
92-
raise ValueError("Model '{0}' not found in child_inlines".format(model.__name__))
93+
raise UnsupportedChildType("Model '{0}' not found in child_inlines".format(model.__name__))
9394

9495
def get_formset(self, request, obj=None, **kwargs):
9596
"""

polymorphic/formsets/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
BasePolymorphicModelFormSet,
1313
BasePolymorphicInlineFormSet,
1414
PolymorphicFormSetChild,
15+
UnsupportedChildType,
1516
polymorphic_modelformset_factory,
1617
polymorphic_inlineformset_factory,
1718
polymorphic_child_forms_factory,
@@ -27,6 +28,7 @@
2728
'BasePolymorphicModelFormSet',
2829
'BasePolymorphicInlineFormSet',
2930
'PolymorphicFormSetChild',
31+
'UnsupportedChildType',
3032
'polymorphic_modelformset_factory',
3133
'polymorphic_inlineformset_factory',
3234
'polymorphic_child_forms_factory',

polymorphic/formsets/models.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,16 @@
55
from django.core.exceptions import ImproperlyConfigured, ValidationError
66
from django.forms.models import ModelForm, BaseModelFormSet, BaseInlineFormSet, modelform_factory, modelformset_factory, inlineformset_factory
77
from django.utils.functional import cached_property
8+
9+
from polymorphic.models import PolymorphicModel
810
from .utils import add_media
911

1012

13+
class UnsupportedChildType(LookupError):
14+
pass
15+
16+
17+
1118
class PolymorphicFormSetChild(object):
1219
"""
1320
Metadata to define the inline of a polymorphic child.
@@ -167,7 +174,7 @@ def _construct_form(self, i, **kwargs):
167174
model = ContentType.objects.get_for_id(ct_id).model_class()
168175
if model not in self.child_forms:
169176
# Perform basic validation, as we skip the ChoiceField here.
170-
raise ValidationError("Child model type {0} is not part of the formset".format(model))
177+
raise UnsupportedChildType("Child model type {0} is not part of the formset".format(model))
171178
else:
172179
if 'instance' in defaults:
173180
model = defaults['instance'].get_real_concrete_instance_class() # respect proxy models
@@ -200,7 +207,18 @@ def get_form_class(self, model):
200207
"""
201208
if not self.child_forms:
202209
raise ImproperlyConfigured("No 'child_forms' defined in {0}".format(self.__class__.__name__))
203-
return self.child_forms[model]
210+
if not issubclass(model, PolymorphicModel):
211+
raise TypeError("Expect polymorphic model type, not {0}".format(model))
212+
213+
try:
214+
return self.child_forms[model]
215+
except KeyError:
216+
# This may happen when the query returns objects of a type that was not handled by the formset.
217+
raise UnsupportedChildType(
218+
"The '{0}' found a '{1}' model in the queryset, "
219+
"but no form class is registered to display it.".format(
220+
self.__class__.__name__, model.__name__
221+
))
204222

205223
def is_multipart(self):
206224
"""

0 commit comments

Comments
 (0)