Django applies the validation rules defined in the Model or Form. But sometimes we might need custom validation in Django admin forms.
Let’s assume that we are developing an app that’ll store all of the countries data. We’ll also feature 5 of them in the homepage of the app. Let’s consider the following Model
file: models.py
from django.db import models class Country(models.Model): name = models.CharField(max_length=30) population = models.IntegerField() is_independent = models.BooleanField() featured = models.BooleanField()
Now if you register this Model, you’ll get auto generated form in Django Admin:
file: admin.py
from myapp.models import Country from django.contrib import admin admin.site.register(Country)
But it’ll never know that you wanted to add at most 5 countries as Featured country. After the 5th featured country if you add another country as featured country it won’t warn you, it’ll just let you do it. But with custom validation you can do what you really wanted.
Create a form (here CountryForm) that extends django.forms.ModelForm. then create a method clean_[field_name]
in that form. Here, we wanted to validate the featured field, so the method name would be clean_featured. And the posted field value is self.cleaned_data['featured']. You can also raise an error message, see the code below:
file: admin.py
from django import forms from myapp.models import Country from django.contrib import admin class CountryForm(forms.ModelForm): class Meta: model = Country def clean_featured(self): featuredCount = Country.objects.filter(featured=True).count() if featuredCount >= 5 and self.cleaned_data['featured'] is True: raise forms.ValidationError("5 Countries can be featured at most!") return self.cleaned_data['featured'] class CountryAdmin(admin.ModelAdmin): form = CountryForm admin.site.register(Country, CountryAdmin)
Thank you for posting this – it was helpful.
Thank you, just what I was looking for. Nowhere in Django documentation could I find a clear explanation on how to validate auto-generated forms.
you’re welcome.
As Emin said, it’s really hard to find clear explanation for this subject at the official documentation and your simple example clicked it immediately!
btw, I would start with the self.cleaned_data['featured'] is True check right as the first line of the function, no need to query the db if its false ;)
Exactly! :)