If you are new to Django REST Framework (DRF), one concept that often confuses beginners is Serializers.
In this article, I’ll break it down in simple terms, show you how to build one from scratch, and explain why they are the most critical part of your API.
What is a Serializer?
In DRF, a serializer is like a bridge between your database and the internet.
Django models store data as Python objects. However, when you want to send that data to a frontend application (like React or a mobile app), you cannot send Python objects. You need to send a format that everyone understands which is usually JSON.
Serializers perform three main jobs:
- Serialization: Converting complex Python objects (Models) into Python dictionaries (which can be easily rendered into JSON).
- Deserialization: Converting JSON data coming from a user back into complex Python objects.
- Validation: Checking if the incoming data is correct before saving it to the database.
Why Do We Need Them?
In a standard Django application, we interact with data using Models. Let's look at a simple scenario. We want to build a store, so we define a ProductModel.
(Create this in your models.py file)
# demo/models.py
from django.db import models
class ProductModel(models.Model):
name = models.CharField(max_length=150)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
stock = models.IntegerField()
is_active = models.BooleanField(default=True)
def __str__(self):
return self.name
If you try to send a ProductModel instance directly to a web browser, it will crash. The browser doesn't speak "Python Class"; it speaks "JSON".
We need a translator. That translator is the Serializer.
Creating Your First Serializer
There are several types of serializers in DRF, such as ModelSerializer, HyperLinkedSerializer, and ListSerializer. To truly understand how they work, we are going to start with the base Serializer class.
We will create a serializers.py file in our app (let's call the app demo) and define a serializer that mirrors our model.
# demo/serializers.py
from rest_framework import serializers
class ProductSerializer(serializers.Serializer):
name = serializers.CharField(max_length=150)
description = serializers.CharField()
price = serializers.DecimalField(max_digits=10, decimal_places=2)
stock = serializers.IntegerField()
is_active = serializers.BooleanField()
Notice that we had to repeat the fields from the Model. We will solve this redundancy in Part 2, but for now, this explicit style helps us understand exactly what is happening.
Seeing Serialization in Action
The best way to learn DRF is not through the web browser, but through the Python Shell. This allows us to see the data transformation step-by-step.
Open your terminal and run. Make sure your python virtual environment where you have installed Django and Django Rest Framework is active.
python manage.py shell
First, let's import our model and serializer.
from demo.models import ProductModel
from demo.serializers import ProductSerializer
Step 1: Create Dummy Data
Let's create a product in our database using standard Django code.
product = ProductModel.objects.create(
name='Logitech MX Master',
description='Ergonomic Logitech Mouse',
price=110.99,
stock=72,
is_active=True
)
Step 2: Serialize the Data
Now, we pass this product object into our serializer.
serializer = ProductSerializer(product)
To see the translated data, we access the .data attribute.
print(serializer.data)
Output:
{
'name': 'Logitech MX Master',
'description': 'Ergonomic Logitech Mouse',
'price': '110.99',
'stock': 72,
'is_active': True
}
Success! The serializer took a Python Object and converted it into a Python Dictionary. This dictionary can now be easily turned into JSON and sent over the API.
Deserialization (The Reverse Process)
Now, let's look at the reverse scenario. A user wants to create a new product via your API. They will send you a JSON object.
Let's assume this is the incoming data:
data = {
"name": "Mechanical Keyboard",
"description": "Backlit mechanical keyboard",
"price": "24.99",
"stock": 10,
"is_active": True
}
To convert this raw data back into a Python object, we pass it to the serializer using the data argument:
serializer = ProductSerializer(data=data)
A common mistake beginners make is trying to access the data immediately.
# DO NOT DO THIS
print(serializer.data)
Output:
AssertionError: When a serializer is passed a `data` keyword argument you must call `.is_valid()` before attempting to access the serialized `.data` representation.
DRF protects your database. It refuses to let you touch the data until you confirm it is valid. You must call is_valid() first. If the is_valid() method is not called, Python will throw an AssertionError
if serializer.is_valid():
print(serializer.validated_data)
else:
print(serializer.errors)
Since our data matches the requirements (e.g., price is a decimal, stock is an integer, is_active is boolean), it returns True.
Saving the Data
Now that the data is valid, we want to save it to the database. Usually, you would call serializer.save().
However, if you try to run serializer.save() right now, it will fail.
Why? Because the base Serializer class doesn't know how to create a ProductModel. We have to tell it how.
Let's go back to serializers.py and implement the create() method.
class ProductSerializer(serializers.Serializer):
name = serializers.CharField(max_length=150)
description = serializers.CharField()
price = serializers.DecimalField(max_digits=10, decimal_places=2)
stock = serializers.IntegerField()
is_active = serializers.BooleanField()
# We must implement this to support saving data
def create(self, validated_data):
# We unpack the validated data and create a model instance
return ProductModel.objects.create(**validated_data)
Now, back in your shell, if you run:
serializer.save()
It will successfully create the "Mechanical Keyboard" in your database.
Wrap Up
We have successfully built a serializer that can:
- Read a Django Model and convert it to a dictionary (Read).
- Take a dictionary, validate it, and convert it into a Django Model (Write).
But did you notice something annoying?
We repeated a lot of code. We typed name, price, and stock in the Model, and then we typed them again in the Serializer. In a real project with dozens of models, this violates the DRY (Don't Repeat Yourself) principle.
In Part 2, I will introduce the ModelSerializer, a powerful shortcut that writes all this boilerplate code for you automatically.

Top comments (0)