Курс по Django: https://stepik.org/a/183363
На предыдущем
занятии мы с вами определили сериализатор на основе базового класса Serializer
для получения данных в JSON-формате, добавления и изменения уже
существующих в таблице БД. Для этого была использована модель Women и ORM Django. То есть, наш сериализатор
напрямую связан с моделью таблицы БД. Это распространенная схема, поэтому для
нее существует специальный класс сериализатора:
ModelSerializer
который упрощает
текст программы при описании сериализаторов, связанных с моделями фреймворка Django. Давайте
посмотрим, как это будет выглядеть в нашем конкретном случае.
Укажем в
качестве базового класса ModelSerializer для нашего
сериализатора WomenSerializer и тогда уже нет необходимости вручную прописывать
атрибуты для связи с соответствующими атрибутами модели, а также методы create() и update(). А вместо
всего этого пропишем вложенный класс Meta:
class WomenSerializer(serializers.ModelSerializer):
class Meta:
model = Women
fields = ("title", "content", "cat")
В этом классе мы
указываем модель, с которой должен работать данный сериализатор, и набор полей
таблицы (атрибутов модели) для сериализации. Обратите внимание, что внешний
ключ cat мы обозначаем
как в модели, а не cat_id, как в таблице.
Все! Если сейчас
запустить тестовый веб-сервер:
python manage.py runserver
перейти в
программу Postman для имитации
клиентских запросов, выбрать GET-запрос для адреса:
http://127.0.0.1:8000/api/v1/womenlist/
то получим
данные в формате JSON по, указанным в сериализаторе, полям title, content, cat.
Также будут
работать и остальные запросы POST:
{
"title": "Sergei Balakirev",
"content": "Известный программист и преподаватель 21-го века. Его наследие актуально и живо и по сей день.",
"cat": 2
}
и PUT.
Если в
сериализаторе мы собираемся работать со всеми полями модели, то в классе Meta можно
прописать:
class WomenSerializer(serializers.ModelSerializer):
class Meta:
model = Women
fields = "__all__"
И, теперь, при GET-запросе, мы
будем получать список по всем полям таблицы women.
Некоторых из вас
сейчас может обуять праведный гнев, готовых со сверкающим взглядом заявить:
какого «фига» мы на прошлых занятиях сразу не воспользовались этим базовым
классом и вручную прописывали всю реализацию по работе с моделями БД? Обычно,
кстати, при обучении так и делают, сразу показывают вариант с классом ModelSerializer, не объясняя
подробно, что скрывается под капотом. А знать всю поднаготную сериализаторов,
на мой взгляд, необходимо, т.к. в крупных проектах, зачастую, приходится
создавать свои собственные сериализаторы на базе класса Serializer или других
классов-сериализаторов. Поэтому на прошлых занятиях я подробно показывал изнанку
этого процесса.
Класс ListCreateAPIView
Но, раз
разработчики Django REST Framework упростили
определение сериализаторов, связанных с моделью, то, наверное, аналогичное
упрощение должно быть и для классов представлений? И, действительно, в DRF существует
несколько предопределенных базовых классов, о которых подробно можно почитать
на следующей странице официальной документации:
https://www.django-rest-framework.org/api-guide/generic-views/
Они, следующие:
-
CreateAPIView – создание
данных по POST-запросу;
-
ListAPIView – чтение списка
данных по GET-запросу;
-
RetrieveAPIView – чтение
конкретных данных (записи) по GET-запросу;
-
DestroyAPIView – удаление
данных (записи) по DELETE-запросу;
-
UpdateAPIView – изменение
записи по PUT- или PATCH-запросу;
-
ListCreateAPIView – для чтения
(по GET-запросу) и
создания списка данных (по POST-запросу);
-
RetrieveUpdateAPIView
– чтение и изменение отдельной записи (GET-, PUT- и PATCH-запросы);
-
RetrieveDestroyAPIView
– чтение (GET-запрос) и
удаление (DELETE-запрос) отдельной
записи;
-
RetrieveUpdateDestroyAPIView
– чтение, изменение и добавление отдельной записи (GET-, PUT-, PATCH- и DELETE-запросы).
Применяются все
эти базовые классы похожим образом, поэтому мы рассмотрим примеры только
некоторых из них.
У нас в
программе реализуется GET-запрос, по которому возвращается список
записей в JSON-формате.
Очевидно, эту функциональность поддерживают классы ListAPIView и ListCreateAPIView. Мы выберем
второй, чтобы сразу обеспечить возможность добавления данных.
Определим
дочерний класс представления (в файле women/views.py) на базе ListCreateAPIView, следующим
образом:
class WomenAPIList(generics. ListCreateAPIView):
queryset = Women.objects.all()
serializer_class = WomenSerializer
Здесь атрибут queryset должен
ссылаться на словарь с данными для их последующей обработки (сериализации), а
атрибут serializer_class – на
класс-сериализатор, который будет применяться к коллекции queryset.
Осталось только
прописать маршрут для этого класса-представления (в файле drfsite/urls.py):
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/womenlist/', WomenAPIList.as_view()),
# path('api/v1/womenlist/<int:pk>/', WomenAPIView.as_view()),
]
Все, запускаем
тестовый веб-сервер, переходим в программу Postman и выполняем GET-запрос для URL:
http://127.0.0.1:8000/api/v1/womenlist/
видим тот же
список с данными в JSON-формате. При этом в классе WomenAPIList нам
потребовалось прописать всего две строчки кода, благодаря использованию
базового класса ListCreateAPIView.
Если посмотреть
на реализацию класса ListCreateAPIView, то увидим, что
он, в свою очередь, наследуется от двух классов миксинов: ListModelMixin и CreateModelMixin,
а также общего класса GenericAPIView. Вот, кстати, пример использования множественного
наследования в Python. Здесь классы миксинов описывают
базовый функционал по работе с моделями. Давайте перейдем в ListModelMixin. Видим
метод list(), который
читает данные из таблицы БД и прогоняет их через сериализатор, формируя на
выходе JSON-ответ в виде
списка данных. Примерно то же самое мы прописывали вручную, когда создавали
представление с нуля на основе класса APIView. Ну а в классе ListCreateAPIView реализованы два метода:
-
get() – для
обработки GET-запроса;
-
post() – для
обработки POST-запроса.
В целом все
относительно просто и эффективно. Это, кстати, хороший пример использования ООП
для упрощения написания программ. Советую внимательно его изучить и применять
подобные элементы в своих программах.
Так как класс ListCreateAPIView поддерживает
метод POST, то мы также
можем добавлять данные, отправленные по POST-запросу в JSON-формате. Внизу
страницы имеется форма для отправки данных методом POST для добавления
их в БД:
Такая форма
автоматически появляется, если класс представления поддерживает создание и
изменение данных.
На этом мы
завершим это занятие, а на следующем продолжим эту тему и рассмотрим некоторые
другие классы представлений.
Курс по Django: https://stepik.org/a/183363