Möchten Sie zunächst das Erstellen neuer Buchinstanzen oder nur das Aktualisieren vorhandener unterstützen?
Wenn Sie nur neue Buchinstanzen erstellen wollten, könnten Sie so etwas tun ...
class PageSerializer(serializers.Serializer):
text = serializers.CharField(max_length=500)
class BookSerializer(serializers.Serializer):
page = PageSerializer(many=True)
title = serializers.CharField(max_length=50)
def create(self, validated_data):
book = Book.objects.create(title=validated_data['title'])
for item in validated_data['pages']:
page = Page(id=item['page_id'], text=item['text'], book=book)
page.save()
return book
Beachten Sie, dass ich das hier nicht aufgenommen book_id
habe. Wenn wir Buchinstanzen erstellen, wird keine Buch-ID angegeben. Wenn wir Buchinstanzen aktualisieren, fügen wir normalerweise die Buch-ID als Teil der URL und nicht in die Anforderungsdaten ein.
Wenn Sie beide unterstützen möchten erstellen und zu aktualisieren Buch Instanzen dann müssen Sie darüber nachdenken , wie Sie Seiten behandeln , die nicht im Antrag enthalten sind, aber sind derzeit mit dem Buch - Instanz zugeordnet.
Sie können diese Seiten stillschweigend ignorieren und so lassen, wie sie sind. Möglicherweise möchten Sie einen Validierungsfehler auslösen oder sie löschen.
Angenommen, Sie möchten alle Seiten löschen, die nicht in der Anforderung enthalten sind.
def create(self, validated_data):
...
def update(self, instance, validated_data):
instance.title = validated_data['title']
instance.save()
page_ids = [item['page_id'] for item in validated_data['pages']]
for page in instance.books:
if page.id not in page_ids:
page.delete()
for item in validated_data['pages']:
page = Page(id=item['page_id'], text=item['text'], book=instance)
page.save()
return instance
Es ist auch möglich, dass Sie nur Buchaktualisierungen und nicht die Erstellung unterstützen möchten. In diesem Fall sollten Sie nur die update()
Methode einbeziehen.
Es gibt auch verschiedene Möglichkeiten, wie Sie die Anzahl der Abfragen reduzieren können, z. Verwenden von Massenerstellung / -löschung, aber das oben Genannte würde die Arbeit auf ziemlich einfache Weise erledigen.
Wie Sie sehen, gibt es Feinheiten in den Verhaltensweisen, die Sie beim Umgang mit verschachtelten Daten möglicherweise wünschen. Überlegen Sie sich daher genau, welches Verhalten Sie in verschiedenen Fällen erwarten.
Beachten Sie auch, dass ich Serializer
im obigen Beispiel eher als verwendet habe ModelSerializer
. In diesem Fall ist es einfacher, alle Felder explizit in die Serializer-Klasse aufzunehmen, als sich auf den automatischen Satz von Feldern zu verlassen, ModelSerializer
der standardmäßig generiert wird.
you might want to only support book updates ... , only include the update() method
. Wie wirdinstance
in diesem Fall die In-Update-Methode mit einem vorhandenen Buch gefüllt?page_id
.Sie können einfach drf-writable-nested verwenden . Dadurch werden Ihre verschachtelten Serialisierer automatisch beschreibbar und aktualisierbar.
in dir
serializers.py
:from drf_writable_nested import WritableNestedModelSerializer class RequestSerializer(WritableNestedModelSerializer): book_id = serializers.IntegerField() page = PageSerializer(many=True) class PageSerializer(serializers.ModelSerializer): class Meta: model = Page
Und das ist es!
Außerdem unterstützt die Bibliothek die Verwendung nur einer der
create
undupdate
-Logiken, wenn Sie nicht beide benötigen.quelle