- Знакомство с REST.
- Что такое Django REST Framework?
- Установка Django.
1. Создание виртуальной среды.
2. Установка зависимостей.
3. Начало проекта.
4. Изменение директории.
5. Запуск сервера.
6. Создание приложения.
7. Список приложений в проекте.
8. Миграции.
9. Административная панель.
10. Создание модели.
11. Не забывайте о миграциях!
12. Добавление приложения в админ-панель. - Написание Django REST API.
1. Сериализатор.
2. Представления.
3. URL: ссылки на ресурсы. - Выводы.
1. Знакомство с REST
Термин REST API расшифровывается как Representational State Transfer Application Programming Interface. Следовательно, RESTful API — это программный интерфейс приложения, соответствующий ограничениям архитектурного стиля REST.
REST — не протокол и не стандарт. Это, как уже было сказано, архитектурное ограничение. Чтобы API считался RESTful, он должен соответствовать следующим критериям.
- Единый интерфейс.
Единый интерфейс (uniform interface) строится вокруг ресурсов с уникальными идентификаторами и уникальными URL, а каждая страница реализовывает какие-либо из HTTP-методов — GET, POST, DELETE или UPDATE — все они отвечают за различные манипуляции конкретным ресурсом. - Архитектура “Клиент-Сервер”
Сервер анализирует запрос клиента и отправляет ему ответ. Получив ответ от сервера, клиент определяет, как именно информация отобразится у конечных пользователей. - Нестационарные запросы
Нестационарность (stateless) означает, что каждый HTTP-запрос полностью изолирован. Сервер не полагается на информацию из предыдущих запросов — клиент отправляет HTTP-запрос, включающий сразу всю необходимую ему информацию. Сервер не хранит контекста между запросами, каждый запрос содержит всю необходимую информацию.
Благодаря вышеперечисленным архитектурным правилам REST API масштабируемый, переносимый и гибкий.
2. Что такое Django REST Framework?
Django — масштабируемый полнофункциональный веб-фреймворк, написанный на Python. Django берет на себя все хлопоты, зачастую связанные с веб-разработкой, такие как безопасность и доступ к базам данных.
Существует множество библиотек для Django, расширяющих его функционал. Одна из них, о которой мы поговорим сегодня, — это Django REST Framework или DRF, которая позволяет сериализовать данные из Django ORM через REST API.
Сериализация — это преобразование таблиц из базы данных в формат JSON.
Руководство написано для новичков, прошлый опыт работы с фреймворком Django не предполагается, так как вы многому научитесь прямо сейчас. Кроме того, в статье не будет обширного описания технических нюансов каждой операции. Рассматривайте руководство в качестве упражнения.
Давайте создадим сайт бронирования отелей! Исходный код и справка доступны на GitHub.
3. Установка Django
Прежде чем приступить непосредственно к работе с REST API, сделаем краткий экскурс в Django.
3.1. Создание виртуальной среды
$ virtualenv venv
$ source venv/bin/activate
3.2. Установка зависимостей
$ pip install djangorestframework
$ pip install django
3.3. Начало проекта
$ django-admin startproject hotel_reservation
$ cd demo/
3.4. Изменение директории
$ mv hotel_reservation/manage.py .
$ mv hotel_reservation/hotel_reservation/* hotel_reservation/
$ rm -r hotel_reservation/hotel_reservation/
3.5. Запуск сервера
$ python manage.py runserver
Теперь перейдите по адресу http://127.0.0.1:8000/ в браузере. Если все прошло успешно, то вы увидите следующую страницу:
3.6. Создание приложения
Приложения в Django — это независимые многократно используемые компоненты. Создадим приложение hotel_app
.
$ django-admin startapp hotel_app
3.7. Список приложений в проекте
Чтобы подключить к проекту hotel_reservation
приложения hotel_app
и rest_framework
, необходимо отредактировать файл results/settings.py
, указав эти приложения в списке INSTALLED_APPS
:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'hotel_app'
'rest_framework'
]
3.8. Миграции
Теперь нужно выполнить Django-миграции — это способ Django распространять в схему базы данных все изменения, вносимые в модели, такие как добавление поля, удаление модели. Выполняйте эту команду каждый раз, когда модель или база данных сколько-нибудь меняются:
$ python manage.py migrate
3.9. Административная панель
Django поставляется со встроенной панелью администратора, что позволяет создать суперпользователя с помощью одной команды. Заполните форму — появится учетная запись администратора:
$ python manage.py createsuperuser
Для доступа к админ-панели перейдите по ссылке: http://127.0.0.1:8000/admin.
Снова выполните миграции, авторизуйтесь.
3.10. Создание модели
Django ORM абстрагирует базу данных, позволяя легко запрашивать данные и манипулировать ими через объектно-ориентированное отображение, называемое моделью. Django ORM заставляет писать код согласно паттерну MVC (Model View Controller), который станет интуитивно понятным для вас после прохождения кривой обучения.
hotel_app/models.py
:
from datetime import timedelta, datetime
from django.db import models
from datetime import datetime
class Guest(models.Model):
name = models.CharField(max_length=20)
age = models.IntegerField(default=20)
phone = models.CharField(max_length=20)
email = models.CharField(max_length=30)
def __str__(self) -> str:
return self.name
class Hotel(models.Model):
name = models.CharField(max_length=20)
location = models.CharField(max_length=50)
phone = models.CharField(max_length=20)
email = models.CharField(max_length=30)
def __str__(self) -> str:
return self.name
class Room(models.Model):
room_no = models.IntegerField(default=101)
price = models.FloatField(default=1000.0)
hotel = models.ForeignKey(Hotel, on_delete=models.CASCADE)
is_booked = models.BooleanField(default=False)
def __str__(self) -> str:
return str(self.room_no)
def hotel_name(self) -> str:
return self.hotel
class Booking(models.Model):
guest = models.ForeignKey(Guest, on_delete=models.CASCADE)
hotel = models.ForeignKey(Hotel, on_delete=models.CASCADE)
room = models.ForeignKey(Room, on_delete=models.CASCADE)
num_of_guest = models.IntegerField(default=1)
checkin_date = models.DateField(default=datetime.now)
checkout_date = models.DateField(default=datetime.now)
is_checkout = models.BooleanField(default=False)
def __str__(self) -> str:
return self.guest.name
def hotel_name(self) -> str:
return self.hotel.hotel
def charge(self) -> float:
return self.is_checkout* \
(self.checkout_date - self.checkin_date + timedelta(1)).days* \
self.room.price
Мы создали модель, хранящую имя студента и его оценки. Метод __str__
определяет имя объекта, отображаемое в браузере. Если пропустить определение данного метода, то вы увидите в панели администратора объект под названием <ClassName>
.
3.11. Не забывайте о миграциях!
Теперь, когда изменения уже внесены в модель, настало время выполнить миграции.
$ python manage.py makemigrations
$ python manage.py migrateviews.
3.12. Добавление приложения в админ-панель
Во встроенное приложение административной панели можно добавить созданную ранее пользовательскую модель.
hotel_app/admin.py
:
from django.contrib import admin
from .models import Guest, Hotel, Room , Bookingadmin.site.register(Guest)
admin.site.register(Hotel)
admin.site.register(Room)
admin.site.register(Booking)
Теперь мы завершили ту общую часть разработки веб-приложения, которая относится к фреймворку Django. Настало время приступить к проектированию REST API.
4. Написание Django REST API
Структура директорий проекта:
$ tree -I 'venv'
.
├── db.sqlite3
├── hotel_app
│ ├── __init__.py
│ ├── __pycache__
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
| ├── serializer.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── hotel_reservation
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
Добавим в проект файлы urls.py
и serializers.py
. Вот новый список файлов.
4.1. Сериализатор
Сериализация — процесс перевода структуры данных в последовательность байтов. Она используется для передачи объектов по сети и для сохранения их в файлы (Википедия).
hotel_app/serializers.py
:
from rest_framework import fields, serializers
from .models import Guest, Hotel, Room , Booking
class GuestSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Guest
fields = ("name", "age", "phone", "email")
class HotelSerializer(serializers.ModelSerializer):
class Meta:
model = Hotel
fields = ("name", "location", "phone", "email")
class RoomSerializer(serializers.ModelSerializer):
class Meta:
model = Room
fields = ("room_no", "price", "hotel", "is_booked")
class BookingSerializer(serializers.ModelSerializer):
guest = GuestSerializer
hotel = HotelSerializer
room = RoomSerializer
class Meta:
model = Booking
fields =("guest", "hotel", "room", "checkin_date", "checkout_date", "charge",)
Сериализаторы определяют, как именно и какие данные отобразит представление API. При запросе по REST API к экземпляру модели Hotel
мы получим список следующих полей, взятых из самой модели при помощи сериализатора:
{
“name” : “”,
“location” : “”,
“phone” : “”,
“email” : ””,
}
4.2. Представления
Файл представления определяет то, как сериализованные объекты отображаются пользователю.
from rest_framework import status
from rest_framework.response import Response
from rest_framework.decorators import api_view
from .models import Guest, Hotel, Room, Booking
from .serializer import GuestSerializer, HotelSerializer, RoomSerializer, BookingSerializer
from collections import namedtuple
nt = namedtuple("object", ["model", "serializers"])
pattern = {
"guest" : nt(Guest, GuestSerializer),
"hotel" : nt(Hotel, HotelSerializer),
"room" : nt(Room, RoomSerializer),
"booking": nt(Booking, BookingSerializer),
}
@api_view(["GET", "POST"])
def ListView(request, api_name):
object = pattern.get(api_name, None)
if object == None:
return Response(
data = "Invalid URL",
status = status.HTTP_404_NOT_FOUND,
)
if request.method == "GET":
object_list = object.model.objects.all()
serializers = object.serializers(object_list, many=True)
return Response(serializers.data)
if request.method == "POST":
data = request.data
serializers = object.serializers(data=data)
if not serializers.is_valid():
return Response(
data = serializers.error,
status = status.HTTP_404_NOT_FOUND
)
serializers.save()
return Response(
data = serializers.error,
status = status.HTTP_201_CREATED
)
Вышеописанное представление возвращает результат для URL-параметра api_name
при его соответствии одному из следующих значений: guest, hotel, room
или booking
. В противном случае представление отправляет клиенту сообщение Invalid URL
.
4.3. URL: ссылки на ресурсы
hotel_app/urls.py
:
from django.urls import re_path
from .views import ListViewurlpatterns = [
re_path(r"^(?P<api_name>[a-z]+)", ListView, name='hotel-objects'),
]
hotel_reservation/urls.py
:
from django.contrib import admin
from django.urls import path, includeurlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘hotel-app’, include(‘hotel_app.urls’))
]
Таким образом определяется базовый URL-путь для API: http://127.0.0.1:8000/hotel-app/.
Перейдя по данной ссылке, вы получите доступ ко всем ранее определенным “разделам” REST API проекта:
guest
: http://127.0.0.1:8000/hotel-app/guest/.hotel
: http://127.0.0.1:8000/hotel-app/hotel/.room
: http://127.0.0.1:8000/hotel-app/room/.booking
: http://127.0.0.1:8000/hotel-app/booking/.
При попытке запросить какое-либо иное API браузер получит от сервера сообщение об ошибке, так как в приложении бронирования отеля существуют только эти четыре вида API.
Пример:
5. Выводы
Мы успешно реализовали пользовательский интерфейс отправки запросов HTTP-методами GET и POST. API готов, к нему можно получить доступ по соответствующей ссылке. Весь исходный код руководства доступен на GitHub.
Читайте также:
- 4 совета Python Django разработчику
- Галерея лучших модулей Python
- Python Django: контактная форма с автоматической отправкой Email
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи Umangshrestha: Create a REST API with Django