Topics in this subject
Django 3 min read Updated 11 Aug 2026

DRF Serializers

Converting complex data (querysets/models) to JSON and vice-versa.

🧑‍🏫 Sabse pehle — simple mein samjho#

Python ko objects samajh aate hain (jaise Post model), par frontend (React) ko sirf JSON text samajh aata hai. Serializer ek Translator hai. Jab data database se nikalta hai, Serializer us Python object ko JSON mein translate (Serialize) karke bhejta hai. Aur jab frontend naya data JSON mein bhejta hai, Serializer us JSON ko check karta hai (validation) aur phir wapas Python object mein badal kar (Deserialize) database mein save kar deta hai.

1. The Serializer Class#

You can build a standard Serializer (similar to a standard Django Form) by inheriting from serializers.Serializer. However, because we usually map our data directly to database models, we almost exclusively use ModelSerializers (which automatically generate fields based on the model).

Create a new file serializers.py in your app.

serializers.py

from rest_framework import serializers
from .models import Post

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        # You can use '__all__' to include all fields, or specify a list
        fields = ['id', 'title', 'content', 'author', 'created_at']
        
        # You can make certain fields strictly read-only (e.g., they show up in JSON, but cannot be modified via a POST/PUT request)
        read_only_fields = ['author', 'created_at']

2. Using the Serializer in Python Shell#

To understand how it works under the hood, let's look at how data flows through the serializer.

Serialization (Model -> JSON)#

from .models import Post
from .serializers import PostSerializer

# 1. Get an object from the DB
post = Post.objects.first()

# 2. Pass it to the serializer
serializer = PostSerializer(post)

# 3. Access the translated data
print(serializer.data)
# Output: {'id': 1, 'title': 'Hello', 'content': 'World', ...}

Note: If you are serializing a list of multiple items (a QuerySet), you MUST pass many=True: PostSerializer(posts, many=True).

Deserialization (JSON -> Model)#

When receiving data from the frontend (e.g., via a POST request), you pass the raw JSON data to the data parameter.

# Raw incoming dictionary
incoming_data = {'title': 'New Title', 'content': 'New content'}

# 1. Pass data to the serializer
serializer = PostSerializer(data=incoming_data)

# 2. ALWAYS call is_valid() before saving to ensure constraints are met!
if serializer.is_valid():
    # 3. Save it to the database. Because it's a ModelSerializer, it knows how to create() automatically!
    serializer.save()
    print("Saved successfully!")
else:
    # If it fails, print exactly which field caused the error
    print(serializer.errors)

3. Nested Serializers (Handling Relationships)#

If a Post model has a ForeignKey to a User (the author), by default, the Serializer will just output the User's ID (e.g., 'author': 1). What if you want the full User object nested inside the JSON?

You use a nested serializer!

from django.contrib.auth.models import User

# First, create a basic serializer for the User
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'email']

class PostSerializer(serializers.ModelSerializer):
    # Override the default 'author' field with our new UserSerializer!
    # read_only=True ensures clients can't accidentally update user details while updating a post
    author = UserSerializer(read_only=True)

    class Meta:
        model = Post
        fields = ['id', 'title', 'content', 'author']

Now, the JSON output will look like this:

{
  "id": 1,
  "title": "Hello",
  "content": "World",
  "author": {
    "id": 4,
    "username": "tarun",
    "email": "t@t.com"
  }
}