Wprowadzenie.
We wpisie przedstawiłem kolejną klasę generyczną RetrieveUpdateAPIView, dzięki której jesteśmy w stanie odczytywać określone rekordy z bazy danych oraz je aktualizować. Ze względu, że mechanizm odczytywania jest taki sam jak przy już omawianej klasie generycznej RetrieveDestroyAPIView, dlatego w tym wpisie przedstawię jedynie funkcjonalność aktualizacji danych.
Spis treści serii
- Django REST API cz. 1– Tworzenie nowego projektu
- Django REST API cz. 2 – ListAPIView
- Django REST API cz. 3 – Wbudowana strona logowania
- Django REST API cz. 4 – Widoki generyczne
- Django REST API cz. 5 – ListCreateAPIView i konfiguracja dostępu
- Django REST API cz. 6 – Uszczegóławianie odpowiedzi
- Django REST API cz. 7 – Określenie z góry wartości danych
- Django REST API cz. 8 – RetrieveDestroyAPIView
- Django REST API cz. 9 – RetrieveUpdateAPIView ⇐
- Django REST API cz. 10 – Nadpisywanie zachowań metod przed/po operacji zapisu/usuwania
- Django REST API cz. 11 – Rejestracja nowego użytkownika poprzez API
- Django REST API cz. 12 – Uwierzytelnianie przy pomocy Tokena
- Django REST API cz. 13 – Generowanie tokena dla istniejących użytkowników
Zakres artykułu.
- Aktualizacja rekordów w bazie danych – RetrieveUpdateAPIView
Aktualizacja rekordów w bazie danych - RetrieveUpdateAPIView
Wyobraźmy sobie następującą sytuację. Po wypełnieniu i wysłaniu formularza z wypożyczeniem książki, popełniliśmy błąd i wybraliśmy nie tą książkę co chcieliśmy. W takim przypadku możemy albo usunąć dany rekord co już dobrze znamy lub też zmienić dane w tym rekordzie. W celu zmienienia danych może na przykład zastosować klasę generyczną RetrieveUpdateAPIView. Napiszmy zatem nową klasę widoku, która będzie miała następującą postać.
class BorrowRetrieveUpdate(generics.RetrieveUpdateAPIView): queryset = Borrow.objects.all() serializer_class = BorrowSerializer permission_classes = [IsAuthenticated]
Standardowo kolejnym krokiem jest stworzenie ścieżki url do wywołania naszej klasy. Ta część kodu wygląda następująco path(‘api/borrows//edit/’, views.BorrowRetrieveUpdate.as_view()).
urlpatterns = [ path('admin/', admin.site.urls), # API path('api/authors/', views.AuthorList.as_view()), path('api/books/', views.BookList.as_view()), path('api/borrows/', views.BorrowList.as_view()), path('api/borrows/<int:pk>/', views.BorrowRetrieveDestroy.as_view()), path('api/borrows/<int:pk>/edit/', views.BorrowRetrieveUpdate.as_view()), # new # DRF path('api-auth/', include('rest_framework.urls')), ]
Ostatnim krokiem jest przetestowanie, czy wszystko poprawnie działa. Przejdźmy zatem pod adres 127.0.0.1:8000/api/borrows/, w celu wybrania interesującego nas rekordu. W moim przypadku będzie to rekord o id 9.
Następnie przejdźmy pod adres 127.0.0.1:8000/api/borrows/9/edit/.
Jak widzimy po wprowadzeniu powyższego adresu, odczytaliśmy dane rekordu o id 9, a na dole mamy formularz, który jak się przyjrzymy, możemy wysłać metodą PUT. Dla przypomnienia metoda PUT odpowiedzialna jest za aktualizację całego rekordu.
Po wprowadzeniu danych i wysłaniu formularza metodą PUT dane zostaną zaktualizowane.
Sprawdźmy jeszcze dla pewności czy dane zostały zaktualizowane, gdy wpiszemy adres 127.0.0.1:8000/api/borrows.
Jak widzimy, wszystko ładnie działa, choć tak naprawdę nie do końca, ponieważ aktualnie jesteśmy w stanie modyfikować także dane wypożyczeń innych użytkowników. W takim przypadku musimy wykonać podobne czynności jak przy usuwaniu rekordów.
Nadpiszmy zatem metodę PUT w taki sposób, aby filtrowała nam zwracany obiekt nie tylko po pk, lecz również po użytkowniku, który wysyła zapytanie. W przypadku, jeżeli obiekt będzie istniał, wówczas zostanie wywołana metoda update, zgodnie ze standardowym procesem, a w przypadku, gdy obiekt nie będzie istniał, wówczas zostanie zwrócony błąd, który poinformuje, że nie jesteśmy właścicielem tego wypożyczenia.
class BorrowRetrieveUpdate(generics.RetrieveUpdateAPIView): queryset = Borrow.objects.all() serializer_class = BorrowSerializer permission_classes = [IsAuthenticated] def put(self, request, *args, **kwargs): borrow = Borrow.objects.filter(pk=kwargs['pk'], user_id=self.request.user) if borrow.exists(): return self.update(request, *args, **kwargs) else: raise ValidationError('You are not the owner')
Możemy teraz ponownie przetestować, czy gdy będziemy chcieli zmodyfikować wypożyczenie inne niż nasze, system rzeczywiście zwróci nam błąd.
Przejdźmy pod adres 127.0.0.1:8000/api/borrows/, aby zobaczyć pełną listę wypożyczeń.
Jak możemy zauważyć, nie jesteśmy właścicielem wypożyczenia o id 4. Przejdźmy zatem pod adres 127.0.0.1:8000/api/borrows/4/edit/.
W tym miejscu warto zaznaczyć, że jesteśmy w stanie odczytać nie nasz rekord, ponieważ dokonaliśmy modyfikacji jedynie metody PUT, która jest odpowiedzialna za modyfikację, a nie odczyt danych.
Wprowadźmy zmodyfikowane dane do formularza i wyślijmy go metodą PUT.
Jak widzimy, API zwróciło nam informację, że nie jesteśmy właścicielami tego wypożyczenia. Przejdźmy teraz do wyświetlenia listy wypożyczeń.
Zgodnie z oczekiwaniami rekord o id 4 nie został zmodyfikowany.
Spis treści serii
- Django REST API cz. 1– Tworzenie nowego projektu
- Django REST API cz. 2 – ListAPIView
- Django REST API cz. 3 – Wbudowana strona logowania
- Django REST API cz. 4 – Widoki generyczne
- Django REST API cz. 5 – ListCreateAPIView i konfiguracja dostępu
- Django REST API cz. 6 – Uszczegóławianie odpowiedzi
- Django REST API cz. 7 – Określenie z góry wartości danych
- Django REST API cz. 8 – RetrieveDestroyAPIView
- Django REST API cz. 9 – RetrieveUpdateAPIView ⇐
- Django REST API cz. 10 – Nadpisywanie zachowań metod przed/po operacji zapisu/usuwania
- Django REST API cz. 11 – Rejestracja nowego użytkownika poprzez API
- Django REST API cz. 12 – Uwierzytelnianie przy pomocy Tokena
- Django REST API cz. 13 – Generowanie tokena dla istniejących użytkowników