Создаём API для сайта на Django c использованием REST framework
24.02.2025
24.02.2025
7 минут
106
0
1
0
0
Вступление
Доброго времени суток. На примере моего проекта SearchResultParser я покажу как можно сделать API для вашего сайта и то, как этот API можно будет использовать со стороны клиента. Бэкенд я пишу на Django, а за создание и настройку его API будет заниматься Django REST framework.
Процесс создания Django REST API для сайта можно описать следующими шагами:
- Создаём проект и предварительно устанавливаем все необходимые пакеты, настраиваем его
- Создаём модели которые, хотим использовать на стороне клиента
- Создаём сериализаторы к ним.
- Создаём представления(обработчики) для них
- Подключаем роутеры и пути
- Пишем и настраиваем клиент для работы с API
По объективным причинам 1 пункт я пропущу, ибо проект SRP уже создан и настроен, можешь посмотреть как его настроить и привести в рабочий вид, а я тем временем опишу дальнейшие шаги.
Добавлю ещё то, что ты должен будешь установить и подключить следующие python-модули:
- django-cors-headers: для активации так называемого Cross-Origin Resource Sharing (CORS) для общения React приложения и Django API.
- djangorestframework: это Django приложение, которое позволит нам с лёгкостью построить АПИ для нашего сайта.
- django: бэкенд нашего сайта, управление базой данных
Вот так, подключи ново установленные модули в settings.py:
Так же, прошу заметить я имею отдельное приложение Backend. Там будет весь мой API. Его тоже нужно подключить, ибо там мы и будем всё писать.
Настраиваем REST API для Django, создаём модели
Итак, сейчас мой сайт SearchResultPaser имеет систему парсинга данных из поисковых систем. На момент написания данной статьи, только Google. Плюс возможность добавлять новые поисковые системы и удалять старые. Но, данный сайт не ограничивается этим.
У меня ещё должны быть, так называемые пресеты, то есть, говоря на языке джанго, модель Preset, которая будет доступна каждому зарегистрированному пользователю для сохранения и настройки их любимых поисковых запросов.
Вот полный код модели, на её примере мы и будем заниматься сереализацией:
Как можно видеть, у данной модели есть связь ManyToMany (Одна запись в таблицу Preset может быть связана со множеством записей в БД, модели Query) с моделью Query. Query - это обёртка для хранения запросов пользователей. Хочу обратить внимание, я буду сохранять только те запросы, которые необходимы для персета. В общем-то, ничего особенного в данной модели больше нет. Расмотрим уже модель Query:
Она ещё проще, есть текстовое поле query и связь ForeignKey со следующей моделью SearchEngine(Одна запись в таблицу Query, может иметь связь только с одной записью модели SearchEngine).
Ну и конечно модель SearchEngine:
У каждой записи данной модели есть текущее состояние. Ready - значит, пользователь может его выбрать на сайте и получить соответствующий результат парсинга. InDevelopment - значит соответствующий парсер ещё не написан и его нельзя использовать сейчас. И последний статус, NeedsSetup, означает, что пользователь может использовать данный парсер, как и в первом случае, но предварительно требуется настройка в профиле пользователя.
Так же хочу отметить поле config. Каждая поисковая система уникальна при попытке её парсинга, через официальный API. В любом случае добавлять и удалять записи в таблицу SearchEngine, могу и должен только я.
Настраиваем REST API для Django, создаём сериализаторы
Чтобы иметь возможность работать с данными моделями на стороне клиента (через JS), нам потребуются Сереализаторы. Для этого импортируем модуль serializers из rest_framework и пишем, то что хотим сериализовать:
Ничего особенного в этих сериализаторах нет. Создаём класс посредством наследования. Потом выбираем модель и поля, которые хотим сериализовать. Двигаемся дальше.
Настраиваем REST API для Django, создаём особые представления
Теперь, нам бы видеть что мы добавляем, удаляем или изменяем. Нужно создать представления в файле Backend/views.py:
Пройдёмся по каждому из них. PresetModelView, его особенность в том что мы фильтруем все наши пресеты в зависимости от пользователя, который хочет их получить. Особенностью SearchEngineModelView, является, то что её можно только просматривать, но не добавлять или удалять записи из БД нельзя.
Настраиваем REST API для проекта, подключаем представления
И последний штрих. Чтобы наконец увидеть в действии REST API, нужно подключить созданные ранее классы-представления: QueryModelViews, SearchEngineModelViews и PresetModelView. Для этого в файле Backend/urls.py подключим новый роутер:
Всё, готово. Давай посмотрим что получилось. Перейди по адресу localhost:8000/api/ , ты увидишь, что-то вроде этого:

Как видно из картинки мы успешно подключили и настроили наш роутер. Перейдём по любой из представленных ссылок, например localhost:8000/api/se/

Или например, давай посмотрим страницу пресетов, ради чего собственно это всё и затевалось. Итак, у меня есть две учётные записи dima и some и у каждой свои пресеты. Посмотрим как работает фильтрация по пользователю:

Пользователь some

Пользователь dima
Как видно, у первого пользователя только один пресет с id=3. А у второго 2 пресета с id=1 и 2.
Дополнительная настройка REST фреймворка
У тебя наверняка возник вопрос, что всё это красиво, но хочется просто получить JSON файл на стороне клиента и сделать то что должно. У меня так же зудело и я нашёл довольно элегантное решение для данной проблемы.
Смотри, в режиме разработки нам будут показываться предыдущие страницы на картинках, но если мы поменяем режим (т.е. сделаем debug=False в settings.py) мы будем получать вот такие вот ответы:

Чтобы добиться такого результата, достаточно добавить в конце файла settings.py следующие строчки:
Мы просто меняем рендер по умолчанию и получаем то, что получаем ... JSON файл.
Работа с API со стороны клиента
Работать с API со стороны клиента, очень просто. Необходимо сделать соответствующий AJAX запрос и обработать ответ. Например, так я получу все доступные записи в SearchEngine модели.
Для примера, я хочу добавлять разные иконки статусов для каждого из поискового движка. Чтобы получить непосредственные данные из ответа, мы обратимся к специальному объекту data в ответе и после к необходимым нам полям. И в зависимости от статуса движка, мы либо добавим ему обработчик, либо нет.
Да, я понимаю, этот блок кода гораздо сложнее, с вложенными друг в друга запросами. Но этот пример идеально подходит для демонстрации того, как можно получить данные из ответа.
А вот и ответы с сервера:

Для localhost:8000/api/se/

Для localhost:8000/api/seue/
И то, как это может выглядеть на сайте:

Заключение
Вот и закончили мы настройку API нашего сайта при помощи Django REST фреймворка. Конечно, по началу может показаться что всё это как-то запутанно и чересчур сложно, но поверь, когда твой проект станет чуть-чуть сложней, чем одностраничный лендинг, ты сразу вспомнишь про REST фреймворк и про то, что он не такой уж и запутанный ( •̀ ω •́ )y
Комментарии
(0)
Отправить
Сейчас тут пусто. Буть первым (o゚v゚)ノ
Другое
Использованные термины
- Axios библиотека ⟶ Это JavaScript-библиотека для выполнения либо HTTP-запросов в Node.js, либо XMLHttpRequests в браузере. Она поддерживает промисы — новинку ES6. Одна из особенностей, которая делает её лучше fetch() — автоматические преобразования JSON-данных.
- CORS (Cross-Origin Resource Sharing) ⟶ Это механизм, который позволяет ограничить ресурсы веб-страниц, чтобы они могли запросить ресурсы с других доменов. Поскольку правила безопасности браузеров по умолчанию блокируют такие запросы (из-за политики одинаковых источников), CORS предоставляет способ более безопасного доступа к ресурсам с других источников.
Релевантные вопросы
- В чём отличие OneToOne от ForeingKey полей ? Их основным и главным отличием является то, как они относятся к модели на которую они ссылаются. Если отношение между моделью с полем OneToOne и целевой моделью, такие, что может быть только одна такая запись в БД, то ForeignKey допускает не ограниченное количество оных.
- Когда использовать поле связи OneToOne в Django моделях ? Данное поле модели отлично подойдёт, когда необходимо добавить новый функционал к уже существующей модели (или вернее сказать, к записи модели в БД). То есть, тогда, когда менять существующий функционал уже созданных моделей не оправдано тяжело или дорого.