|
5 | 5 | from django.core.exceptions import ImproperlyConfigured, ValidationError
|
6 | 6 | from django.forms.models import ModelForm, BaseModelFormSet, BaseInlineFormSet, modelform_factory, modelformset_factory, inlineformset_factory
|
7 | 7 | from django.utils.functional import cached_property
|
| 8 | + |
| 9 | +from polymorphic.models import PolymorphicModel |
8 | 10 | from .utils import add_media
|
9 | 11 |
|
10 | 12 |
|
| 13 | +class UnsupportedChildType(LookupError): |
| 14 | + pass |
| 15 | + |
| 16 | + |
| 17 | + |
11 | 18 | class PolymorphicFormSetChild(object):
|
12 | 19 | """
|
13 | 20 | Metadata to define the inline of a polymorphic child.
|
@@ -167,7 +174,7 @@ def _construct_form(self, i, **kwargs):
|
167 | 174 | model = ContentType.objects.get_for_id(ct_id).model_class()
|
168 | 175 | if model not in self.child_forms:
|
169 | 176 | # 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)) |
171 | 178 | else:
|
172 | 179 | if 'instance' in defaults:
|
173 | 180 | model = defaults['instance'].get_real_concrete_instance_class() # respect proxy models
|
@@ -200,7 +207,18 @@ def get_form_class(self, model):
|
200 | 207 | """
|
201 | 208 | if not self.child_forms:
|
202 | 209 | 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 | + )) |
204 | 222 |
|
205 | 223 | def is_multipart(self):
|
206 | 224 | """
|
|
0 commit comments