Django – #30 – REST API cz. 6 – Uszczegóławianie odpowiedzi

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.

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.

Autor artykułu
Dominik Bednarski

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.