Po pierwsze, czy chcesz wesprzeć tworzenie nowych instancji książek, czy tylko aktualizować istniejące?
Jeśli tylko kiedykolwiek chciał stworzyć nowe instancje książki można zrobić coś takiego ...
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):
# Create the book instance
book = Book.objects.create(title=validated_data['title'])
# Create or update each page instance
for item in validated_data['pages']:
page = Page(id=item['page_id'], text=item['text'], book=book)
page.save()
return book
pamiętać, że nie obejmowały book_id
tutaj. Podczas tworzenia instancji książek nie będziemy uwzględniać identyfikatora książki. Gdy aktualizujemy instancje książek, zazwyczaj podajemy identyfikator książki jako część adresu URL, a nie w danych żądania.
Jeśli chcesz obsługiwać tworzenie i aktualizowanie instancji książek, musisz zastanowić się, w jaki sposób obsługiwać strony, które nie są zawarte w żądaniu, ale są obecnie powiązane z instancją książki.
Możesz zignorować te strony i pozostawić je w niezmienionej postaci, możesz zgłosić błąd sprawdzania poprawności lub możesz je usunąć.
Załóżmy, że chcesz usunąć wszystkie strony nieuwzględnione w żądaniu.
def create(self, validated_data):
# As before.
...
def update(self, instance, validated_data):
# Update the book instance
instance.title = validated_data['title']
instance.save()
# Delete any pages not included in the request
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()
# Create or update page instances that are in the request
for item in validated_data['pages']:
page = Page(id=item['page_id'], text=item['text'], book=instance)
page.save()
return instance
Jest również możliwe, że chcesz tylko aktualizacjach książki wsparcie, a nie wspierać tworzenie, w którym to przypadku, tylko obejmują metodę update()
.
Istnieje również wiele sposobów na zmniejszenie liczby zapytań, np. przy użyciu zbiorczego tworzenia/usuwania, ale powyższe czynności byłyby wykonywane w dość prosty sposób.
Jak widać, istnieją subtelności w typach zachowań, które mogą być przydatne w przypadku zagnieżdżonych danych, więc należy dokładnie przemyśleć, jakiego zachowania oczekuje się w różnych przypadkach.
Należy również zauważyć, że użyłem w powyższym przykładzie Serializer
zamiast ModelSerializer
. W takim przypadku prostsze jest tylko jawne uwzględnienie wszystkich pól w klasie serializera, zamiast polegania na automatycznym zestawie pól generowanych domyślnie przez ModelSerializer
.
'może chcesz tylko wspierać aktualizacje książek ..., dołącz tylko metodę update()". W takim przypadku, w jaki sposób metoda "instancji" w aktualizacji zostanie wypełniona istniejącą książką? – norbertpy
Poprzez utworzenie instancji serializatora za pomocą argumentu słowa kluczowego "instancja". Zwykle otrzymasz to, wykonując wyszukiwanie oparte na kluczu podstawowym w adresie URL. Jeśli używasz ogólnych widoków, które będą dla Ciebie obsługiwane. Spójrz na DetailMixin w "mixins.py" na potrzeby implementacji tego. –
Dzięki Tom. Mam to teraz. – norbertpy