Как сериализовать абстрактные базовые модели и подмодели в REST-фреймворке Django

У меня есть модель Complaint, которая может иметь множество Evidence. Модель Evidence может быть Attachment или Link и является абстрактной базовой моделью .

from django.db import models


class Complaint(models.Model):
    text = models.TextField()


class Evidence(models.Model):
    complaint = models.ForeignKey(
        Complaint,
        related_name='%(class)s_evidences',
        on_delete=models.CASCADE
    )
    is_attached = models.BooleanField()

    class Meta:
        abstract = True


class Attachment(Evidence):
    file = models.FileField(upload_to='attachments')


class Link(Evidence):
    url = models.URLField()

Я хочу иметь возможность принимать входные данные Complaint и все его Evidence из одного представления следующим образом:

{
    "text": "Lorem ipsum",
    "evidences": [
        {
            "description": "dolor sit amet",
            "is_attached": false,
            "url": "https://example.com"
        },
        {
            "description": "consectetur adipisicing elit",
            "is_attached": true,
            "file": "http://localhost:8000/media/attachments/filename"
        }
    ]
}

Вот что у меня есть в моем serializers.py на данный момент:

from rest_framework import serializers

from .models import Complaint, Evidence, Attachment, Link


class EvidenceSerializer(serializers.Serializer):  # since ModelSerializer can not be used with abstract models
    id = serializers.IntegerField(read_only=True)
    is_attached = serializers.BooleanField()

    class Meta:
        abstract = True
        model = Evidence
        fields = ['id', 'is_attached']


class AttachmentSerializer(EvidenceSerializer, serializers.ModelSerializer):
    class Meta:
        model = Attachment
        fields = EvidenceSerializer.Meta.fields + ['file']


class LinkSerializer(EvidenceSerializer, serializers.ModelSerializer):
    class Meta:
        model = Link
        fields = EvidenceSerializer.Meta.fields + ['url']


class ComplaintSerializer(serializers.ModelSerializer):
    evidences = EvidenceSerializer(many=True)

    class Meta:
        model = Complaint
        fields = ['id', 'text', 'evidences']

При запросе к представлению жалобы POST (/lodge) возникает следующая ошибка:

TypeError at /lodge
Got a `TypeError` when calling `Complaint.objects.create()`. This may be because you have a writable field on the serializer class that is not a valid argument to `Complaint.objects.create()`. You may need to make the field read-only, or override the ComplaintSerializer.create() method to handle this correctly.

Внизу трассировки:

TypeError: Complaint() got an unexpected keyword argument 'evidences'

Как мне написать сериализаторы для этих моделей?

В сообщении об ошибке говорится о необходимости переопределить Complaint.objects.create, но я не знаю, как это сделать. Я пытался следовать примеру, приведенному для записываемых вложенных сериализаторов в официальной документации, но он не использует абстрактные модели.

Вернуться на верх