# How to perform data validation in Django Rest Framework?

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.

```python
# 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`.

```python
# 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.

```python
# 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.

```python
# 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/](https://www.linkedin.com/in/mnamegaurav/)
    
*   **YouTube:** [https://www.youtube.com/devjunction](https://www.youtube.com/devjunction)
    
*   **Website:** [https://gaurav.devjunction.in/](https://gaurav.devjunction.in/)
    
*   **GitHub:** [https://github.com/mnamegaurav](https://github.com/mnamegaurav)
    
*   **Instagram:** [https://www.instagram.com/mnamegaurav/](https://www.instagram.com/mnamegaurav/)
    
*   **Twitter:** [https://twitter.com/mnamegaurav](https://twitter.com/mnamegaurav)
