Reputation: 583
I would like to validate a Many-to-many field in Django admin by overriding the clean method.
This thread gives a way to do that by creating a ModelForm and then doing the clean there. However, my problem is the many-to-many field is an inline i.e. instead of the widget where you have to select multiple elements, I have a tabular inline.
I would like to find out if anyone knows how to add the inlines in the ModelForm so that I can do the clean and validation. I've seen people talk about inlineformset_factory but it's always been as it relates to views.py and not the admin (and I can't figure out how I'd even go about overriding the clean method of that).
I've added some of my code below:
class ProductVariantForm(ModelForm):
class Meta:
model = ProductVariant
fields = [ 'name',
'price',
]
# I then want to be able to add something like
# inlines = [OptionValueInline,]
# for the inline many-to-many field.
def clean(self):
# Check if list of option_values is ok.
class ProductVariantAdmin(admin.ModelAdmin):
form = ProductVariantForm
Upvotes: 0
Views: 2267
Reputation: 583
My solution to the problem is based on this post.
class ProductVariantOptionValueInlineFormSet(BaseInlineFormSet):
def clean(self):
super().clean()
data = self.cleaned_data
# do whatever validation on data here
class ProductVariantOptionValueInline(admin.TabularInline):
model = ProductVariant.option_values.through
formset = ProductVariantOptionValueInlineFormSet
class ProductVariantAdmin(admin.ModelAdmin):
inlines = [
ProductVariantOptionValueInline,
]
exclude = ('option_values',)
Upvotes: 0
Reputation: 449
Adding an inline is a feature of the Admin itself. See this doc for more info about inlines. Afaik, you can't add an inline to just a plain form (or a ModelForm
).
To check the validity of the data in an inline, you could use the form
property of the InlineModelAdmin
class. This way you can access the clean
method of the inline form directly.
To elaborate, it is split this way because the inlines are a separate form in Django's terms, concerning different data and running separate queries. They are all submitted in one HTTP request, but that is all they have in common. So it doesn't really make sense to use the main ModelForm
for the inline data.
Upvotes: 1