I have the following code:
from django import forms
from django.core.exceptions import ValidationError
class MyAdminForm(forms.ModelForm):
class Meta:
model = MyModel
def clean(self):
cleaned_data = self.cleaned_data
max_num_items = cleaned_data['max_num_items']
inline_items = cleaned_data.get('inlineitem_set', [])
if len(inline_items) < 2:
raise ValidationError('There must be at least 2 valid inline items')
if max_num_items > len(inline_items):
raise ValidationError('The maximum number of items must match the number of inline items there are')
return cleaned_data
I thought I could access the formset from the cleaned_data (by using cleaned_data['inlineitem_set']) but that doesn’t seem to be the case.
My questions are:
- How do I access the formset?
- Do I need to create a custom formset with my custom validation for this to work?
- If I need to do that, how do I access the “parent” form of the formset in its
cleanmethod?
I’ve just solved this for my own project. It does appear, as suggested in your 2nd question, that any inline formset validation requiring access to the parent form needs to be in the
cleanmethod of aBaseInlineFormsetsubclass.Happily, the parent form’s instance gets created (or retrieved from the database, if you’re modifying rather than creating it) before the inline formset’s
cleanis called, and it is available there asself.instance.The try-except pattern here is guarding against an
AttributeErrorcorner case that I haven’t seen myself but which apparently arises when we try to access thecleaned_dataattribute of a form (inself.forms) that failed to validate. Learned about this from https://stackoverflow.com/a/877920/492075(NB: my project is still on Django 1.3; haven’t tried this in 1.4)