📝 Django

Nested Serializers in DRF

P
Author
Pyland
📅
Published
30.06.2026
⏱️
Reading time
1 min
👁️
Views
78
📊
Level
Article

Охватываемые темы: Reading Nested Objects, Write by ID, Read as Object, Nested List (Reverse Relation), Writing Nested Objects.

Reading Nested Objects

class ProjectSerializer(serializers.ModelSerializer):
    class Meta:
        model = Project
        fields = ['id', 'name']

class TaskSerializer(serializers.ModelSerializer):
    project = ProjectSerializer(read_only=True)  # nested object

    class Meta:
        model = Task
        fields = ['id', 'title', 'status', 'project']

API response:

{
  "id": 1,
  "title": "Task",
  "project": {"id": 5, "name": "My Project"}
}

Write by ID, Read as Object

class TaskSerializer(serializers.ModelSerializer):
    project = ProjectSerializer(read_only=True)         # for GET
    project_id = serializers.PrimaryKeyRelatedField(    # for POST/PUT
        queryset=Project.objects.all(),
        source='project',
        write_only=True,
    )

    class Meta:
        model = Task
        fields = ['id', 'title', 'project', 'project_id']

Nested List (Reverse Relation)

class TaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = Task
        fields = ['id', 'title', 'status']

class ProjectSerializer(serializers.ModelSerializer):
    tasks = TaskSerializer(many=True, read_only=True)  # via related_name='tasks'

    class Meta:
        model = Project
        fields = ['id', 'name', 'tasks']

Writing Nested Objects

class ProjectSerializer(serializers.ModelSerializer):
    tasks = TaskSerializer(many=True)

    class Meta:
        model = Project
        fields = ['id', 'name', 'tasks']

    def create(self, validated_data):
        tasks_data = validated_data.pop('tasks', [])
        project = Project.objects.create(**validated_data)
        for task_data in tasks_data:
            Task.objects.create(project=project, **task_data)
        return project

    def update(self, instance, validated_data):
        tasks_data = validated_data.pop('tasks', [])
        instance = super().update(instance, validated_data)
        # Update tasks...
        return instance

SerializerMethodField

class TaskSerializer(serializers.ModelSerializer):
    project_name = serializers.SerializerMethodField()

    def get_project_name(self, obj):
        return obj.project.name if obj.project else None

Your reaction to the article

💬 Comments (0)

🔐 Sign in to leave a comment
🚪 Login
💭

No comments yet

Be the first to share your opinion about this article!

🔗 Similar

Similar articles

Continue learning with these materials

📝

pytest-django: Testing Django

Охватываемые темы: Installation, @pytest.mark.djangodb, Fixtures, Testing views.

📅 30.06.2026 👁️ 132
📝

Django: Template Tags

Template tags are logic inside HTML. Unlike {{ variable }} which only outputs a value,...

📅 30.06.2026 👁️ 85
📝

Django: Static Files

Static files are CSS, JavaScript, images, and fonts. Django handles them in a specific way:...

📅 30.06.2026 👁️ 73

Did you like the article?

Subscribe to our updates and receive new articles first. Grow with PyLand!