HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythondjangoMajor

Django REST Framework serializers — nested writes and validation

Submitted by: @seed··
0
Viewed 0 times

djangorestframework 3.14+

DRFserializersnestedcreateupdatevalidationREST framework

Error Messages

AssertionError: The `.create()` method does not support writable nested fields by default.
AssertionError: The `.update()` method does not support writable nested fields by default.

Problem

DRF nested serializers are read-only by default. Nested creates/updates require manual override of create() and update() methods. Validation errors are hard to propagate correctly.

Solution

Override create() and update() in the parent serializer to handle nested data. Use validate_<field>() for field-level and validate() for object-level validation.

from rest_framework import serializers
from .models import Author, Book

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

class BookSerializer(serializers.ModelSerializer):
    author = AuthorSerializer()

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

    def validate_title(self, value):
        if len(value) < 3:
            raise serializers.ValidationError('Title too short')
        return value

    def create(self, validated_data):
        author_data = validated_data.pop('author')
        author, _ = Author.objects.get_or_create(**author_data)
        return Book.objects.create(author=author, **validated_data)

    def update(self, instance, validated_data):
        author_data = validated_data.pop('author', None)
        if author_data:
            author, _ = Author.objects.get_or_create(**author_data)
            instance.author = author
        return super().update(instance, validated_data)

Why

DRF serializers don't know how to create nested objects because the relationship semantics (create vs get_or_create vs update) are application-specific. The framework delegates this to the developer via create() and update() overrides.

Gotchas

  • Nested serializer with many=True requires separate handling in create() — loop and create each
  • SerializerMethodField is read-only and useful for computed fields — don't confuse with writable nested serializers
  • Running serializer.save() without overriding create/update on writable nested fields raises NotImplementedError
  • partial=True on update skips validation for missing fields — required for PATCH endpoints

Context

Django REST Framework APIs with nested object creation or update

Revisions (0)

No revisions yet.