Rohan Yeole - HomepageRohan Yeole

How to Use clean() and clean_<fieldname>() in Django

By Rohan Yeole
When working with Django forms or models, sometimes you need more control over how your data is validated.

That’s where Django’s clean() and clean_<fieldname>() methods come in.

They let you write custom rules to make sure your data is just the way you want it—before it gets saved or used.

In this article, I’ll break down what these methods do, when to use each one, and how to use them with simple examples.

What is clean_<fieldname>()?


Let’s say you’re building a signup form, and you don’t want users to pick certain usernames like “admin” or “support”.

Django lets you handle that using a method called clean_<fieldname>().

Here’s how it works-
from django import forms
from django.core.exceptions import ValidationError

class SignUpForm(forms.Form):
username = forms.CharField(max_length=30)

def clean_username(self):
username = self.cleaned_data.get('username')
if username.lower() in ['admin', 'support']:
raise ValidationError("This username is not allowed.")
return username
This method only runs when the username field is being validated. It’s perfect for handling one field at a time.

Tip: You can apply this to any field—just replace username with the name of the field you want to validate.

What is clean()?


Now imagine you have two fields—like a password and a confirm password—and you want to make sure they match.

You can’t do that in a single clean_<fieldname>() method, because it involves comparing two fields.

That’s where the main clean() method comes in. This method runs after all the individual fields are cleaned, and it has access to all your form data.

Here’s a simple example-
class PasswordResetForm(forms.Form):
new_password = forms.CharField(widget=forms.PasswordInput)
confirm_password = forms.CharField(widget=forms.PasswordInput)

def clean(self):
cleaned_data = super().clean()
password1 = cleaned_data.get("new_password")
password2 = cleaned_data.get("confirm_password")

if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords do not match.")

return cleaned_data
This is great when you need to check that two or more fields work together in the right way.

What About Models?


These methods also work with Django models—not just forms.

If you’re using a model form or manually saving model data, you can define a clean() method inside your model to add extra validation before saving.

Example-
from django.db import models
from django.core.exceptions import ValidationError

class Booking(models.Model):
start_date = models.DateField()
end_date = models.DateField()

def clean(self):
if self.end_date < self.start_date:
raise ValidationError("End date cannot be before start date.")

Then, before saving-

booking = Booking(start_date='2025-05-10', end_date='2025-05-05')
booking.full_clean() # This will raise a ValidationError
booking.save()

Best Practices

  • Use clean_<fieldname>() when your validation is only about one field.
  • Use clean() when you need to compare or combine multiple fields.
  • Always return the cleaned data in your clean() method.
  • if you’re working with models, don’t forget to call full_clean() before saving, especially if you’re not using a ModelForm.

Want to Dive Deeper?


You can learn more about Django’s validation process straight from the official documentation here. It’s a great next step if you want to dig into advanced use cases.

Final Thoughts


Both clean() and clean_<field>() are powerful — and once you get when to use each, your form and model logic becomes way easier to manage and debug. 

Use field-specific validation where possible, and reach for clean()   when your logic spans multiple fields.

If you're struggling with form behavior or field validation, understanding Django's validation flow is a game changer. And if you haven't yet, check out mine full breakdown of Beginner’s Guide to Django Models and Forms (With Examples) — it’ll fill in the gaps.