Serializers Overview0%

Serializers Overview

Beginner12 min read•Updated: Jul 11, 2026
Study MaterialsCheatsheet

DRF Serializers: Serialization and Deserialization

At the heart of Django REST Framework lies the Serializer. Serializers act as the bidirectional translator between complex Python objects (such as Django ORM model instances and QuerySets) and structured data formats (primarily JSON). They also enforce strict input validation during data ingestion.


1. The Serialization Pipeline (Read / GET)

When a client queries an endpoint, Django model instances are converted into Python primitive types, which are subsequently rendered into JSON:

Output
Database Record ──► Django Model Instance ──► DRF Serializer.data ──► JSON String ──► Client
Python
# Example: Serializing a single model instance
from articles.models import Article
from articles.serializers import ArticleSerializer
 
article = Article.objects.get(id=1)
serializer = ArticleSerializer(article)
print(serializer.data)
# Output: {'id': 1, 'title': 'Django ORM', 'slug': 'django-orm', 'content': '...'}

When serializing QuerySets containing multiple items, many=True is mandatory:

Python
articles_queryset = Article.objects.all()
serializer = ArticleSerializer(articles_queryset, many=True)
print(serializer.data)
# Output: [{'id': 1, ...}, {'id': 2, ...}]

2. The Deserialization Pipeline (Write / POST / PUT)

When a client sends data to create or update a resource:

Output
Client JSON ──► Request.data dict ──► Serializer(data=payload) ──► is_valid() ──► save()
Python
# Ingesting client JSON
payload = {"title": "New Article", "content": "Article body text..."}
serializer = ArticleSerializer(data=payload)
 
# Validation MUST be executed before accessing validated_data or calling save()
if serializer.is_valid(raise_exception=True):
# Persist instance to database
article_instance = serializer.save(author=request.user)

raise_exception=True automatically throws a serializers.ValidationError, which DRF translates into an HTTP 400 Bad Request containing structured error messages.


3. Custom Field-Level and Object-Level Validation

Field-Level Validation (validate_<field_name>)

Python
class ProductSerializer(serializers.Serializer):
name = serializers.CharField(max_length=100)
price = serializers.DecimalField(max_digits=10, decimal_places=2)
 
def validate_price(self, value):
if value <= 0:
raise serializers.ValidationError("Price must be strictly greater than zero.")
return value

Object-Level Cross-Field Validation (validate)

Python
def validate(self, data):
# Cross-field verification
start_date = data.get("start_date")
end_date = data.get("end_date")
 
if start_date and end_date and start_date > end_date:
raise serializers.ValidationError({
"end_date": "End date cannot occur prior to start date."
})
return data

4. Serializer vs ModelSerializer

  • serializers.Serializer: Base class. Requires declaring every field manually (name = serializers.CharField()) and writing explicit create() and update() methods. Used for non-model inputs or third-party API proxies.
  • serializers.ModelSerializer: Automates field creation, relational mapping, unique validators, and database persistence directly from a Django model.

Interactive Quiz

Practice Quiz

Question 1
Why is many=True required when initializing a serializer with a QuerySet?
Question 2
What happens if you call serializer.save() before calling serializer.is_valid()?
Question 3
What is the benefit of calling serializer.is_valid(raise_exception=True)?
Question 4
Where are validated inputs stored after serializer.is_valid() succeeds?
Question 5
In custom validation, what exception class must be raised when an invalid value is detected?
Next Lesson

Function-Based Views & Class-Based Views

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Related Lessons

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext