How to perform data validation in Django Rest Framework?
Three ways to perform data validation in Django Rest Framework serializers
In Django Rest Framework (DRF), we get serializers
to serialize our native Python data types into JSON
or XML
, serializers
can also perform deserialization along with serialization. This means a serializer can convert a native Python data type such as List, Tuple, Querysets etc. into a representable JSON
format, as well as it can take JSON
and convert it back to the relevant python data type.
Django Rest Framework applies data validation at the time of deserialization, that is why we need to call is_valid()
method before accessing the validated data from a serializer instance. If the data is invalid, in this case, errors are then appended to the serializer's error property and a ValidationError
will be thrown.
We can apply data validation in various ways, in this blog, we will have a look at three ways we can apply data validation in a Django Rest Framework (DRF) serializer.
For this blog, we are going to use ModelSerializer
and which will be based on the given model throughout this blog.
# app_name/models.py
from django.db import models
class Book(models.Model):
name = models.CharField(max_length=100)
rating = models.PositiveSmallIntegerField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
...
Instance (object) validation:
If you have a Book
model as given above, and you want to validate the whole instance
, here is how you can perform instance
validation.
In Django Rest Framework (DRF) serializers, we can use a validation()
method to perform object
or instance
level validation, which will take object
or instance
as an argument
and always return the instance
of the Model
if not then it will raise a ValidationError
.
# app_name/serializers.py
from rest_framework import serializers
from app_name.models import Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = '__all__'
def validate(self, data):
if data['author'] == self.context["request"].user:
raise serializers.ValidationError('Logged in User is not an Author')
return data
Field level validation:
If you have a Book
model as given above, and you want to validate certain fields such as rating
for that model, here is how you can perform field-level validation.
The thing to note here is that if you are performing the validation on a field, the validate_FIELD_NAME
method will be used which will always return the validated value, if not then it will raise a ValidationError
.
In the below example, we are validating whether the logged-in user is an author or not.
# app_name/serializers.py
from rest_framework import serializers
from app_name.models import Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = '__all__'
def validate_rating(self, value):
if value < 1 or value > 10:
raise serializers.ValidationError('Rating has to be between 1 and 10.')
return value
Validation through validators:
In the above example of Field level validation, we have validated the field through a method validate_FIELD_NAME
, but you can also create a custom validator to perform such an operation.
# app_name/serializers.py
from rest_framework import serializers
from app_name.models import Book
def is_rating_valid(value):
if value < 1:
raise serializers.ValidationError('Value cannot be lower than 1.')
elif value > 10:
raise serializers.ValidationError('Value cannot be higher than 10')
class BookSerializer(serializers.ModelSerializer):
rating = serializers.IntegerField(validators=[is_rating_valid])
class Meta:
model = Book
fields = '__all__'
That’s it for this blog, there can be some other ways as well if you want to perform some validation, but it is highly recommended that you should perform the data validation in the serializer if possible.
Any thoughts? Write it down in the comments.
For more such crispy blogs daily, follow Dev.Junction, subscribe to our newsletter and get notified.
Social Links
LinkedIn: https://www.linkedin.com/in/mnamegaurav/
YouTube: https://www.youtube.com/devjunction
Website: https://gaurav.devjunction.in/
GitHub: https://github.com/mnamegaurav
Instagram: https://www.instagram.com/mnamegaurav/
Twitter: https://twitter.com/mnamegaurav