How to add custom form with validations in django inline admin

In this tutorial, we will learn how to customize your Django inline admin forms.

Prerequisite.

Django Inline Admin with examples in detail

In this tutorial, we are customizing our inline admin model forms by

  • Adding placeholder and classes in form fields by 2 methods.
  • Adding validation in the form.
# models.py

from django.db import models
from django.utils.safestring import mark_safe


class Product(models.Model):
    title = models.CharField(max_length=150)
    short_description = models.TextField(max_length=100)

    def __str__(self):
        return self.title



class Variant(models.Model):
    product = models.ForeignKey(
        Product, on_delete=models.CASCADE
        )
    size = models.CharField(max_length=100)
    quantity = models.PositiveIntegerField(default=1)
    price = models.DecimalField(max_digits=12, decimal_places=2)

    def __str__(self):
        return self.product.title

After running migrations, register your model in admin panel.

# admin.py

from django.contrib import admin

from .models import (
    Product, Variant
)

admin.site.register(Variant)
    

class ProductVariantInline(admin.TabularInline):
    model = Variant
    readonly_fields = ('id',)
    extra = 1

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    inlines = [ProductVariantInline]

Now go to the admin panel. And you will see variant inlines are added to our product model admin.

Now you can see the variants inline form. What we will do now we will customize these variant forms by adding 

1. Placeholder

2. Validation for the price should be less than 1000

3. Validation for quantity should be less than 20

Now go to your forms.py and create VariantForm

from django import forms
from django.forms import inlineformset_factory
from django.core.exceptions import ValidationError

from .models import (
    Product, Variant
)

def validate_price(value):
    if value > 1000:
        msg = 'Price must be less than or equal to 1000'
        raise ValidationError(msg)


class VariantForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['price'].validators.append(validate_price)

        for visible in self.visible_fields():
            visible.field.widget.attrs['class'] = 'form-control'
            visible.field.widget.attrs['placeholder'] = visible.field.label

    class Meta:
        model = Variant
        exclude = ('product', )


    def clean_quantity(self):
        quantity = self.cleaned_data['quantity']
        if quantity >= 20:
            msg = 'Quantity should be less than 20'
            raise forms.ValidationError(msg)
        return quantity

Note: You can add validation using clean_fieldname() function or by adding validator like "validate_price()".

Now add this form in your admin.py variant inline.

# admin.py

from django.contrib import admin

from .models import (
    Product, Variant
)
from .forms import VariantForm

admin.site.register(Variant)
    

class ProductVariantInline(admin.TabularInline):
    model = Variant
    readonly_fields = ('id',)
    extra = 1
    form = VariantForm    # new line

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    inlines = [ProductVariantInline]

Now go to your admin panel and you will see the placeholder in the variant form field and also do test your validators. I hope it is clear to you.

Related Articles.

Django Inline Admin with examples in detail

Django Inline Formset Factory with Examples.

How to set at least one inline form required in django inline formset

I would greatly appreciate it if you subscribe to my YouTube channel, Let's Code More

 ⋅  0 comments have been posted.

Your comment

Required for comment verification
claps