DRF Writable Nested

0.7.2 · active · verified Wed Apr 15

drf-writable-nested provides helpers for django-rest-framework (DRF) serializers, enabling creation and update of nested objects in a single API call. It simplifies handling related fields, especially for one-to-many and many-to-many relationships, making nested serializer operations more intuitive. The current version is 0.7.2, and it maintains an active release cadence, frequently updating for new Django, DRF, and Python versions.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to use `WritableNestedModelSerializer` to create and update a `Planet` object along with its associated `Moon` objects. It defines `Planet` and `Moon` models, then sets up a `MoonSerializer` and a `PlanetSerializer`. By including `MoonSerializer` as a nested field in `PlanetSerializer` and inheriting from `WritableNestedModelSerializer`, you can perform atomic create/update operations for both parent and child objects with a single serializer. Uncomment the example usage lines to test within a Django shell environment.

from django.db import models
from rest_framework import serializers
from drf_writable_nested.serializers import WritableNestedModelSerializer

# Define models
class Planet(models.Model):
    name = models.CharField(max_length=100, unique=True)
    population = models.BigIntegerField(default=0)

    def __str__(self):
        return self.name

class Moon(models.Model):
    name = models.CharField(max_length=100, unique=True)
    planet = models.ForeignKey(Planet, on_delete=models.CASCADE, related_name='moons')

    def __str__(self):
        return self.name

# Define nested serializer for Moon
class MoonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Moon
        fields = ['id', 'name']

# Define main serializer for Planet using WritableNestedModelSerializer
class PlanetSerializer(WritableNestedModelSerializer):
    moons = MoonSerializer(many=True, required=False)

    class Meta:
        model = Planet
        fields = ['id', 'name', 'population', 'moons']

# Example usage (requires Django setup, e.g., via manage.py shell)
# p = Planet.objects.create(name='Earth', population=8000000000)
# m = Moon.objects.create(name='Luna', planet=p)
# print(PlanetSerializer(p).data)

# Create a new planet with moons
# data = {
#     'name': 'Mars',
#     'population': 0,
#     'moons': [
#         {'name': 'Phobos'},
#         {'name': 'Deimos'}
#     ]
# }
# serializer = PlanetSerializer(data=data)
# serializer.is_valid(raise_exception=True)
# new_planet = serializer.save()
# print(new_planet.name, new_planet.moons.all())

# Update an existing planet and its moons
# existing_earth = Planet.objects.get(name='Earth')
# update_data = {
#     'population': 8100000000,
#     'moons': [
#         {'id': Moon.objects.get(name='Luna').id, 'name': 'The Moon'},
#         {'name': 'New Moon'}
#     ]
# }
# serializer = PlanetSerializer(existing_earth, data=update_data, partial=True)
# serializer.is_valid(raise_exception=True)
# updated_planet = serializer.save()
# print(updated_planet.name, updated_planet.moons.all())

view raw JSON →