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.

models.py

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

admin.py

@admin.register(Post)
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.

@admin.register(Post)
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.


DJANGO

Latest Articles

Latest from djangocentral

Capturing Query Parameters of request.get in Django

In Django, the request object contains a variety of information about the current HTTP request, including the query parameters. Query parameters are a way to pass additional information in the URL and are used to filter or sort data. The request object p…
Read more →

2 min read

Understanding related_name in Django Models

In Django, related_name is an attribute that can be used to specify the name of the reverse relation from the related model back to the model that defines the relation. It is used to specify the name of the attribute that will be used to access the relat…
Read more →

2 min read