Django 5 для начинающих

Прогресс по курсу:  9/1004

8.2 Django REST Framework на примере блога
1 из 1 шага пройден

Django REST Framework

Django REST Framework (DRF) — это широко используемая полнофункциональная платформа API, предназначенная для создания RESTful API с помощью Django. По своей сути DRF интегрируется с основными функциями Django — моделями, представлениями и URL-адресами — что упрощает создание RESTful API.

DRF состоит из следующих компонентов:

  1. Сериализаторы используются для преобразования Django QuerySets и экземпляров моделей в (сериализация) и из (десериализация) JSON (и ряд других форматов рендеринга данных, таких как XML и YAML).

  2. Представления (наряду с наборами представлений), которые похожи на традиционные представления Django, обрабатывают HTTP-запросы и ответы RESTful. Само представление использует сериализаторы для проверки входящих полезных данных и содержит необходимую логику для возврата ответа. Наборы представлений связаны с маршрутизаторами , которые сопоставляют представления с открытыми URL-адресами.

  3. Маршрутизаторы: определяют URL-адреса, которые будут предоставлять доступ к каждому представлению.

 

Установка Django REST Framework

Работать с данным фреймворком мы будем на основе нашего блога. Мы прекрасно понимаем что вряд ли блогу когда-то понадобится API функции, но так вам будет проще разобраться с DRF, так как в блоге уже реализованы функции постов, регистрация и авторизация и тд.

Давайте установим DRF введя в консоли следующий текст:

pip install djangorestframework


Затем добавьте его в раздел INSTALLED_APPS нашего файла mysite/settings.py.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog.apps.BlogConfig',
    'taggit',
    'django.contrib.sites',
    'django.contrib.sitemaps',
    'django.contrib.postgres',
    'accounts.apps.AccountsConfig',
    'social_django',
    'django_bootstrap5',
    # API new
    'rest_framework',
]

REST_FRAMEWORK = {
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.AllowAny",
    ],
}

По умолчанию Django REST Framework настроен на AllowAny, чтобы облегчить нам локальную разработку, однако это не безопасно. Мы разберем эту настройку разрешений в следующих разделах.


Следующим шагом создадим новое приложение, назовем его blog_api.

python manage.py startapp blog_api


Не забываем зарегистрировать наше приложение в settings.py:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog.apps.BlogConfig',
    'taggit',
    'django.contrib.sites',
    'django.contrib.sitemaps',
    'django.contrib.postgres',
    'accounts.apps.AccountsConfig',
    'social_django',
    'django_bootstrap5',
    # API new
    'rest_framework',
    'blog_api.apps.BlogApiConfig', # new
]


А в файл mysite/urls.py добавим новый маршрутизатор:

path("api/", include("blog_api.urls")),


Хорошей практикой является постоянное версионирование API, поскольку при внесении больших изменений может возникнуть некоторая задержка, прежде чем различные потребители API также смогут обновиться.

Например создание маршрутов типа:

path("api/v1/", include("blog_api_v1.urls")), # API версия 1
path("api/v2/", include("blog_api_v2.urls")), # API версия 2

 Поможет вам поддерживать v1 API в течение определенного периода времени, одновременно запуская новую, обновленную v2, и избегая поломки других приложений, которые полагаются на бэкэнд вашего API.


Теперь помощью DRF мы сделаем маршруты вывода нашего списка постов с возможностью доступа к каждому посту. Для этого в папке blog_api создадим urls.py следующего содержания:

from django.urls import path
from .views import PostList, PostDetail

urlpatterns = [
    path("<int:pk>/", PostDetail.as_view(), name="post_detail"),
    path("", PostList.as_view(), name="post_list"),
]

В верхней части файла мы импортировали два представления - PostList и PostDetail - о которых мы напишем в файле views.py, и они соответствуют списку всех постов блога по пустой строке, "", что означает по адресу api/.

Отдельные подробные посты будут находиться по их первичному ключу pk, так что первая запись блога будет будет находиться по адресу api/1/, вторая - по адресу api/2/, и так далее.


Пока что это все стандартные вещи Django, которые мы рассматривали в разделе 2.4 Диспетчер URL.
Теперь нам нужно создать наши представления и сериализаторы, в следующих разделах мы сделаем это.


  • Комментария
Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий

Неплохо было бы тут в теории добавить абзац для чего мы вообще ставим в наш блог API и какую функцию (понятно что учебную) он будет выполнять. Возможно об этом есть дальше, но это нужно тут. Просто сходу с теории API в установку и реализацию идем, а ты просто не врубаешься зачем мы это делаем, нет общей картины.

И (по моему мнению) нужно больше таких схем по всему курсу, возможно в конце каждого раздела. Файлы постоянно множатся как и каша в голове новичков, схемой можно показывать связи между этими файлами или различными приложениями.

Для меня например сейчас встал вопрос который должен был быть закрыт где-то вначале, для чего мы вообще создаем отдельные приложения каждый раз для какого-либо функционала? Почему, например, accounts нельзя было сделать в blog, что там такого?  Те же представления, урлы и прочее.
P.S. Перечитал еще раз степ 2.3 про приложения - Как и когда вы разделите функциональность на приложения - вопрос субъективный, но в целом каждое приложение должно иметь четкую функцию. Стало малость понятнее, но вопрос полностью не снят - это все полностью на наше усмотрение? В какой момент необходимо понять, что вот - сейчас приложение "блог" мне пора разделить на приложение "блог" и приложение "посты". Ведь аккаунты мы вынесли из блога в отдельное приложение, почему бы посты не вынести? 

@Георгий_Тимофеев, мы можем работать в одном приложении, но на сколько будет удобно вам его поддерживать когда будет куча разных представлений и форм в одних файлах? Поэтому мы создали еще одно приложение accounts, чтобы разделить логику блога и логику юзера. Разделять блог нет смысла, у нас внутри одна логика, отвечающая за посты.

У блога 2.0 вообще будет другая структура, но задача у этого одна, создать как можно больше удобств при обслуживании и доработках проекта. Например, один из моих проектов, посмотрите на структуру:

Тут разделение не только по приложениям, а еще и внутри разделена логика по папкам. То есть модели, формы, представления и менеджеры моделей размещены в отдельных папках и отдельными файлами. Просто когда у вас модель + функции размером в 100+ символов, и даже если таких моделей порядка даже 5. То в одном файле models.py размером на 500 строк не совсем будет приятно с ними работать.

@Георгий_Тимофеев, на самом деле в нашем случае, API у блога не несет никакой функциональности. Основная цель познакомить с DRF и создать API.

@Илья_Перминов

То в одном файле models.py размером на 500 строк не совсем будет приятно с ними работать.

Но тут надо будет не забыть и не запутаться в зависимостях? А есть какая-то схема зависимостей? Чтобы не забыть что при создании нового приложения я его добавляю в сеттингс, а при создании собственных урлов приложения нужно объявить папку в с этими урлами в основном файле urls.py? (Эти я уже запомнил но наверняка их десятки при постоянном создании новых файлов). 

@Георгий_Тимофеев, Не совсем понял вопроса. Если посмотреть на скриншот, то файл urls.py мы не делим, он же относительно не большой. То есть у нас есть главный urls.py проекта, к которому подключаются urls.py файлы приложений. Это, как сейчас, у нашего проекта, где мы подключаем приложение блог и аккаунтс.

По поводу зависимостей, тут да, чуть сложнее их подключать, например вот так модели придется подключать:

from modules.sound.models.daw import Daw
from modules.sound.models.genre import Genre
from modules.sound.models.category import Category
Изменен Илья Перминов

@Илья_Перминов, я сейчас не конкретно про ваш проект говорил а в целом и неправильно выразился. Имел ввиду не зависимости которые импортируем где надо, а надстройки которые необходимо добавлять и прописывать когда мы добавляем что-то новое. Например в тот же settings.py мы уже добавили очень много новых переменных, вот я и спрашивал, есть ли где инфа когда и куда такие надстройки добавлять. Но вот сейчас читаю и понимаю что мой вопрос туповат потому что наверняка в доке пишется, что если вы подключаете что-то, то вот сюда и вот сюда вы должны добавить такие-то переменные. А запомнить увы только с опытом))

 

спасибо в общем за развернутый ответ.

@Георгий_Тимофеев, посмотрите документацию по файлу настроек: https://docs.djangoproject.com/en/5.0/ref/settings/, там всевозможные настройки описываются. Так-же в документации различных библиотек описывается что необходимо добавить в файл настроек, обычно всегда есть примеры. Запоминать это не нужно, достаточно знать где это можно посмотреть.

@Дмитрий_Селезнев, сохранил, спасибо

Хорошей практикой является постоянное версионирование API, поскольку при внесении больших изменений может возникнуть может возникнуть некоторая задержка, прежде чем различные потребители API также смогут обновиться.

@Григорий_Кожанов, спасибо, поправил.

'blog_api.apps.BlogApiConfig' запятая в settings.py?

@Anonymous_450292901, добавил, спасибо.

 Поможет вам поддерживать v1 API в течение определенного периода времени, одновременно запуская новую, обновленную v2, и избегая поломки других приложения,

надо окончание поправить

@Виктор_Русинович, исправил, спасибо.