Wprowadzenie.
Tworząc API, należy pamiętać o optymalizacji liczby zapytań wysyłanych do serwera, w celu zmniejszenia odciążenia. W większości przypadków lepiej, żeby pojedyncza odpowiedź posiadała więcej danych, niż żebyśmy wysyłali wiele dodatkowych zapytań. Wysłanie kilku zapytań sumarycznie zajmie więcej czasu. W tym wpisie przedstawię, w jaki sposób możemy dokonać tej oto optymalizacji.
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.
- Uszczegóławianie odpowiedzi
Uszczegóławianie odpowiedzi
W pierwszej kolejności zalogujmy się na konto admina, tak abyśmy mieli dostęp do wszystkich opcji. Następnie w przeglądarce wpiszmy następujący adres url http://127.0.0.1:8000/api/borrows i przyjrzyjmy się otrzymanej odpowiedzi.
Jak możemy zobaczyć w tym konkretnym przykładzie, otrzymanych danych nie jesteśmy w stanie szybko zweryfikować. Załóżmy, że sprawdzamy, aktualny stan wypożyczeń i widzimy, że czas wypożyczenia dla jednej z pozycji dobiega końca. W tym przypadku chcemy poinformować taką osobę, żeby zwróciła nam wypożyczoną książkę, lecz jedyne co możemy odczytać to id użytkownika oraz id książki. Niestety przez taką postać odpowiedzi jesteśmy zmuszeni ponownie wysłać nawet dwa dodatkowe zapytania o dane książki spod konkretnego id oraz o dane użytkownika o danym id. Na szczęści, dzięki DRF jesteśmy w stanie dokonać modyfikacji takiej odpowiedzi, tak aby zoptymalizować liczbę zapytań serwera i otrzymać komplet interesujących nas danych.
W pierwszej kolejności dodajmy do odpowiedzi tytuł wypożyczonej książki. W tym celu należy zmodyfikować plik serializers.py a konkretnie klasę BorrowSerializer(). We wspomianej klasie dodajmy zmienną na przykład book i zwróćmy do niej wynik następującej metody serializers.CharField(source=’book_id.title’). Nowo utworzoną zmienną możemy teraz dodać do listy pól. Więcej szczegółów odnośnie dostępnych funkcjonalności możemy znaleźć pod tym linkiem.
from rest_framework import serializers from .models import Author, Book, Borrow class AuthorSerializer(serializers.ModelSerializer): class Meta: model = Author fields = ['id', 'first_name', 'last_name'] class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = ['id', 'title', 'author_id'] class BorrowSerializer(serializers.ModelSerializer): book = serializers.CharField(source='book_id.title') # new class Meta: model = Borrow fields = ['id', 'user_id', 'book_id', 'book', 'borrow_date', 'return_date'] # new
Wprowadzając powyższą modyfikacją, sprawdźmy, jak prezentuje się nasza odpowiedź.
Uważam, że teraz wygląda to nieco lepiej, ponieważ już nie mamy tylko id książki, ale również posiadamy jej nazwę.
Niestety taka modyfikacja nie do końca nam pasuje, ponieważ choć odpowiedź jest dobra, to niestety, teraz przy wysyłaniu requesta POST, musimy wpisać sami nazwę książki, a przecież i tak ją wybieramy w polu Book id. W związku z tym problemem, ponownie wróćmy do modyfikowanej klasy i teraz do zmiennej book zwróćmy wynik, innej metody to jest
book = serializers.ReadOnlyField(source=’book_id.title’).
from rest_framework import serializers from .models import Author, Book, Borrow class AuthorSerializer(serializers.ModelSerializer): class Meta: model = Author fields = ['id', 'first_name', 'last_name'] class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = ['id', 'title', 'author_id'] class BorrowSerializer(serializers.ModelSerializer): book = serializers.ReadOnlyField(source='book_id.title') # new class Meta: model = Borrow fields = ['id', 'user_id', 'book_id', 'book', 'borrow_date', 'return_date']
Sprawdźmy, jak to teraz wygląda.
Teraz sytuacja jest już dobra, ponieważ przy żądaniu POST nie ma możliwości wpisania nic w pole książka, bo po prostu nie mamy już tego pola.
Wprowadźmy jeszcze kilka modyfikacji, tak byśmy na przykład mogli zobaczyć autora książki oraz imię, nazwisko i maila osoby wypożyczającej
from rest_framework import serializers from .models import Author, Book, Borrow class AuthorSerializer(serializers.ModelSerializer): class Meta: model = Author fields = ['id', 'first_name', 'last_name'] class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = ['id', 'title', 'author_id'] class BorrowSerializer(serializers.ModelSerializer): book = serializers.ReadOnlyField(source='book_id.title') author_first_name = serializers.ReadOnlyField(source='book_id.author_id.first_name') # new author_last_name = serializers.ReadOnlyField(source='book_id.author_id.last_name') # new user_firts_name = serializers.ReadOnlyField(source='user_id.first_name') # new user_last_name = serializers.ReadOnlyField(source='user_id.last_name') # new user_email = serializers.ReadOnlyField(source='user_id.email') # new class Meta: model = Borrow fields = ['id', 'user_id', 'user_firts_name', 'user_last_name', 'user_email', 'book_id', 'book', 'author_first_name', 'author_last_name', 'borrow_date', 'return_date'] # new
Efekt prezentuje się nastepująco.
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