Naprawdę musisz podzielić rzeczy między widokami a serializerem.
Serializers
Serializer
jest samodzielnym obiektem. Służy do konwertowania modelu Django (lub dowolnego rodzaju struktury danych Pythona) do postaci serializowanej i odwrotnie. Możesz go używać jako takiego, gdziekolwiek chcesz. Nie wymaga nawet rzeczywistego żądania HTTP, o ile nie potrzebujesz identyfikatorów URI w wynikach.
Podklasa ModelSerializer
jest wyspecjalizowanym rodzajem Serializer
, który dodaje funkcje "ładuj z modelu" i "zapisz do modelu". Punkt wejścia "Zapisz do modelu" to metoda save()
. Aby ułatwić nadpisywanie, jego domyślna implementacja przekaże jego pracę do metody serializera w zależności od tego, czy tworzy ona nową instancję modelu, czy aktualizuje ją.
Ma to na celu dostosowanie: daje deweloperowi możliwość zastąpienia samej metody tworzenia, tylko metody aktualizacji lub typowego zachowania. Na przykład, pozwala na wykonywanie tego rodzaju rzeczy:
def save(self, **kwargs):
# Will be done on every save
kwargs['last_changed'] = timezone.now()
return super().save(**kwargs)
def create(self, instance, data):
# Will only be done if a new object is being created
data['initial_creation'] = timezone.now()
return super().create(instance, data)
To jest prosty przykład. Tam pole last_changed
będzie ustawione za każdym razem, gdy obiekt zostanie zapisany, czy to kreacja, czy aktualizacja. Jako sidenote, prawdopodobnie nie chcesz tego robić. Rzeczy takie jak ustawianie pól "last_changed" powinny żyć w widoku, a nie w serializatorze.
Viewsets
w zupełnie innym miejscu, Django REST zaopatrzenie ramowe Viewsets
. Są to zorganizowane zbiory poglądów, dotyczące implementacji interfejsu API CRUD dla modelu. W związku z tym przekształca on funkcjonalność w zestaw metod, a mianowicie create()
, retrieve()
/list()
, update()
i delete()
.
Głównym punktem jest: nie ma żadnego połączenia między metodą zestawu obserwacji create()
a serializerową metodą create()
.
To po prostu zdarza się, że domyślna implementacja metod w viewset wykorzystuje się ModelSerializer
i że domyślna implementacja tego serializer za save()
metoda delegatów zadanie do metod, które mają tę samą nazwę.
Nawiasem mówiąc, o przykład last_changed
, oto jak można to zrobić w widoku:
def perform_create(self, serializer):
now = timezone.now()
serializer.save(initial_creation=now, last_changed=now)
def perform_update(self, serializer):
serializer.save(last_changed=timezone.now())
To funkcjonalnie równoważne powyższym przykładzie, ale mieszka w viewset.
Wnioski
Wracając do Twojego pytania, konkretne rzeczy należy zastąpić zależy od obiektu, który jest odpowiedzialny za zadania, które chcesz dodać.
- Jeśli niestandardowe zachowanie jest częścią procesu serializacji, czyli proces przekształcania surowych danych z powrotem do właściwego modelu Django i zapisywania wyników, to należy zastąpić METODY
Serializer
„s.
- Jeśli, z drugiej strony, twoje niestandardowe zachowanie jest specyficzne dla twojego widoku, to powinieneś zastąpić metody
Viewset
.
Jako podpowiedź, możesz zadać sobie następujące pytanie: jeśli używam tego samego serializera w innym miejscu (może innym widoku), czy powinien on zawsze wyświetlać to zachowanie?
Dzięki za odpowiedź! Jest naprawdę szczegółowy i dogłębny, tak jak tego chcę. +1 :) – Tim