Displaying Custom Validation Exception in Django Admin

2 min read

In this tutorial, we will learn how to show custom validation exceptions on Django admin.

Understanding The Problem

Django admin site will raise exceptions when we try to save objects with non-acceptable values. Often we need to create our custom validators and raise custom exceptions depending on the needs of the project. Like if you want the phone number to be in a particular format or you want to make sure the first name starts with a capital letter.

There are a lot of ways to achieve this but if your goal is to ensure proper validation limited from the admin interface only, then this tutorial is for you.

Note: If creating validators that remain constant throughout the app is your goal, then you should check out this article - Creating Custom Model Validation In Django

Displaying Custom Validation Exception in Django Admin

We will use the popular blog project for this tutorial. The goal is to ensure that the title of the post is in the proper title case.

Displaying Custom Validation Exception in Django

Let's have a look at our existing models.py and admin.py file.


class Post(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True)
    author = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="blog_posts")
    updated_on = models.DateTimeField(auto_now=True)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    status = models.IntegerField(choices=STATUS, default=0)
    summary = models.CharField(max_length=500, null=True, blank=True)

    class Meta:
        ordering = ["-created_on"]

    def __str__(self):
        return self.title


class PostAdmin(SummernoteModelAdmin):
    list_display = ('title', 'slug', 'status', 'created_on')
    list_filter = ('status', 'created_on')
    search_fields = ['title', 'content']
    prepopulated_fields = {'slug': ('title',)}

Now to make custom validators for the admin site we need to create a custom form for our model. So in the same file or in a separate file create a form like this.

from django import forms

class PostForm(forms.ModelForm):
    def clean(self):
        title = self.cleaned_data['title']
        if not title.istitle():
            raise forms.ValidationError({'title': "Not a proper titlecased string"})

The model form comes with the clean() method that is responsible for performing validations.

Take the title value from the cleaned_data dictionary and run the validation through it, if it fails the raise the ValidationError with the exception message.

Finally. we need to link our form with the PostAdmin.

class PostAdmin(SummernoteModelAdmin):
    form = PostForm
    list_display = ('title', 'slug', 'status', 'created_on')
    list_filter = ('status', 'created_on')
    search_fields = ['title', 'content']
    prepopulated_fields = {'slug': ('title',)}

That's it! Save the files run the server navigate to the admin and test the flow.


Latest Articles

Latest from djangocentral

Django 4.1 adds async-compatible interface to QuerySet

The much-awaited pull request for an async-compatible interface to Queryset just got merged into the main branch of Django.Pull Request - https://github.com/django/django/pull/14843 The Django core team has been progressively adding async suppor…
Read more →

3 min read

Making Django Admin Jazzy With django-jazzmin

Django admin is undoubtedly one of the most useful apps of Django. Over the years there has been very little change in the admin app as far as the UX is concerned and it's not a bad thing at all. Django admin was designed to provide a simple and minimali…
Read more →

4 min read