2015-05-23 10 views
17

Wdrażam obecnie djangorestframework dla mojej aplikacji RESTful API. Po zabawie z nim nadal nie rozumiem, co jest używane w serializatorze. Jak rozumiem, CRUD wywołuje tylko 4 główne metody w viewsets.ModelViewSet: create(), retrive(), update() i i destroy().Kiedy są tworzone i aktualizowane w serializatorze djangorestframework?

ja też już próbowałem do debugowania i wydrukować rzeczy, aby zobaczyć, gdy metody .create() i .update() nazywane są zarówno ModelViewSet i ModelSerializer. Najwyraźniej tylko metody w ModelViewSet są wywoływane, gdy robię HTTP verbs. Jednak dla ModelSerializer nie widzę żadnych połączeń w tych 2 metodach. Chcę tylko wiedzieć, jakie są metody używane w ModelSerializer, ponieważ widzę, że ludzie nadpisują te metody dużo w serializatorze.

P/S: Jestem nowicjuszem w djangorestframework + przepraszam za mój angielski, ponieważ nie jestem tubylcem.

Dzięki :)

Odpowiedz

50

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?

+1

Dzięki za odpowiedź! Jest naprawdę szczegółowy i dogłębny, tak jak tego chcę. +1 :) – Tim

3

W projekcie reszta-api Crud jest standardem. Nie ma dużej różnicy w tworzeniu i aktualizacji.

Proszę odnieść się do this i

zobaczyć create() metoda stworzy element.

i

update() sposób należy określić, który element zostać zaktualizowane.

+0

Jaka jest różnica między tymi 2? – Tim

13

I wreszcie zrozumieć, w jaki sposób praca .create() i .update() w Serializer (zwłaszcza ModelSerializer) i jak są one podłączone do Viewsets (zwłaszcza ModelViewSet). Chcę tylko jaśniej wyjaśnić tę koncepcję, jeśli ktoś przyjdzie na to pytanie.

Zasadniczo, 4 metody CRUD w ModelViewSet: .create(), .retrieve(), .update(), a .destroy() będzie obsługiwać połączenia z czasowników HTTP. Domyślnie modele .create() i .update() z ModelViewSet będą wywoływać .create() i .update() z ModelSerializer, wywołując metodę .save() z klasy BaseSerializer.

Metoda save() określa, czy wywoła .create() lub .update() w ModelSerializer, określając, czy obiekt self.instance istnieje, czy też nie.

Powiązane problemy