Q:

Writeable Nested Serializers with PrimaryKeyRelatedField

I'm having a problem creating (nested) serializers for the following models:
class Chapter(Model):
    uuid = UUIDField(primary_key=True, editable=False)
    description = TextField(blank=True)

class Section(Model):
    uuid = UUIDField(primary_key=True, editable=False)
    description = TextField(blank=True)
    chapter = ForeignKey(Chapter, related_name='sections', on_delete=CASCADE)

Here is the serializer for the Chapter model with the create method:
class ChapterSerializer(ModelSerializer):
    uuid = UUIDField(read_only=False)
    sections = SectionSerializer(many=True, read_only=False)

    class Meta:
        model = Chapter
        fields = ('uuid', 'description', 'sections')

    def create(self, validated_data):
        sections = validated_data.pop('sections', [])
        chapter = Chapter.objects.create(**validated_data)

        for section in sections:
            section.update({'chapter': chapter})
            section = Section.objects.create(**section)

        return chapter

And here are two slightly different variants of the Section serializer: 
class SectionSerializer(ModelSerializer):
        uuid = UUIDField(read_only=False)
        chapter = PrimaryKeyRelatedField(read_only=true)

        class Meta:
            model = Section
            fields = ('uuid', 'description', 'chapter')

class SectionSerializer(ModelSerializer):
        uuid = UUIDField(read_only=False)
        chapter = PrimaryKeyRelatedField(queryset=Chapter.objects.all())

        class Meta:
            model = Section
            fields = ('uuid', 'description', 'chapter')

Now if I try to create a new Chapter with nested Sections and the PrimaryKeyRelatedField in the Section serializer has the queryset parameter set, I get the following error:
'sections': [{'chapter': ['Invalid pk "x" - object does not exist.']}]

If I use the variant with the read_only=true parameter, creating a new Chapter with nested Sections works, but now I can no longer create a new Section (Chapter field is set to an existing Chapter UUID) because the chapter field is removed while validating the input data.
django.db.utils.IntegrityError: null value in column "chapter_id" violates not-null constraint

I think I could solve this by duplicating the SectionSerializer, but this seems to be a very crude solution ...
Anyone knowing of an better approach?

A:

OK, answering my own question:
I finally found a way to get a "nestable" and a "writeable" version of the SectionSerializer without code duplication:
class NestedSectionSerializer(ModelSerializer):
    uuid = UUIDField(read_only=False)

    class Meta:
        model = Section
        exclude = ('chapter', )

class SectionSerializer(NestedSectionSerializer):
    url = serializers.HyperlinkedIdentityField(view_name='section-detail')

    class Meta:
        model = Section
        fields = '__all__'

class ChapterSerializer(ModelSerializer):
    url = serializers.HyperlinkedIdentityField(view_name='chapter-detail')
    uuid = UUIDField(read_only=False)
    sections = NestedSectionSerializer(many=True, read_only=False)

    class Meta:
        model = Chapter
        fields = '__all__'

    def create(self, validated_data):
        sections = validated_data.pop('sections', [])
        chapter = Chapter.objects.create(**validated_data)

        for section in sections:
            section.update({'chapter': chapter})
            section = Section.objects.create(**section)

        return chapter

The key here ist to explicitly exclude the reverence to chapter in the "nested" serializer but add it again in the "writeable" serializer. This even scales to deeply nested structures!
And by using inheritance I can avoid most code duplication.

