Частина 1: Мистецтво роботи з Django Rest Framework: Повний посібник для професіоналів від початківця до розгортання

pic

Ця стаття є першою частиною посібника з освоєння Django Rest Framework. Призначена для професіоналів, вона проведе вас крок за кроком від налаштування проекту з нуля до його ефективного розгортання. Наприкінці цієї серії ви отримаєте глибоке розуміння та практичні навички для створення надійних, масштабованих API за допомогою Django Rest Framework.

Django Rest Framework надає міцну основу для створення масштабованих, підтримуваних API. Розуміючи його основні компоненти та принципи роботи, розробники можуть створювати потужні API, які безшовно інтегруються з веб- та мобільними додатками.

Ми розробимо REST-систему для ломбарду для управління користувачами, магазинами, продуктами, клієнтами — коротше, все, що потрібно дилеру.

Розуміння Django Rest Framework та його принципи роботи

Django Rest Framework (DRF) — потужний та гнучкий набір інструментів для створення Web API в Django. Він спрощує процес створення RESTful API, що робить його популярним вибором серед розробників, які потребують створення масштабованих і підтримуваних бекенд-систем. Ось огляд його компонентів і того, як вони взаємодіють.

Основні компоненти Django Rest Framework

  1. Моделі

Моделі в Django визначають структуру ваших таблиць бази даних. Вони є основою для створення та керування даними у вашому додатку. DRF взаємодіє з цими моделями для отримання та збереження даних для API.

Приклад:

from django.db import models  

class Product(models.Model):  
 name = models.CharField(max_length=255)  
 description = models.TextField()  
 price = models.DecimalField(max_digits=10, decimal_places=2)  
 stock = models.IntegerField()  

 def __str__(self):  
 return self.name
  1. Серіалізатори

Серіалізатори в DRF відповідають за перетворення складних типів даних, таких як моделі Django, у формат JSON або інші типи контенту, які можна легко відображати в API. Вони також перевіряють вхідні дані, щоб забезпечити правильну структуру перед їх обробкою.

Приклад:

from rest_framework import serializers  
from .models import Product  

class ProductSerializer(serializers.ModelSerializer):  
 class Meta:  
 model = Product  
 fields = ['id', 'name', 'description', 'price', 'stock']
  1. Види

Види в DRF визначають логіку обробки API-запитів. DRF надає два основних типи видів:

  • Вид на основі функцій (FBVs): Простий і підходить для малих API.
  • Вид на основі класів (CBVs): Більш багаторазові та розширювані, ідеальні для більших проектів.

Приклад:

from rest_framework.generics import ListCreateAPIView  
from .models import Product  
from .serializers import ProductSerializer  

class ProductListCreateView(ListCreateAPIView):  
 queryset = Product.objects.all()  
 serializer_class = ProductSerializer
  1. Маршрутизатори та URL-адреси

Маршрутизатори спрощують маршрутизацію URL, автоматично генеруючи шаблони URL для ViewSets. DRF підтримує як прості маршрутизатори, так і вкладені маршрутизатори для складних структур API.

Приклад:

from rest_framework.routers import DefaultRouter  
from .views import ProductViewSet  

router = DefaultRouter()  
router.register(r'products', ProductViewSet)  
urlpatterns = router.urls
  1. Аутентифікація та дозволи

DRF підтримує різні методи аутентифікації, включаючи аутентифікацію на основі токенів, сесій та користувацькі схеми аутентифікації. Дозволи контролюють доступ до точок API на основі ролей та правил користувачів.

Приклад:

from rest_framework.permissions import IsAuthenticated  

class ProductViewSet(ModelViewSet):  
 queryset = Product.objects.all()  
 serializer_class = ProductSerializer  
 permission_classes = [IsAuthenticated]
  1. Обмеження та лімітування запитів

DRF має вбудовані механізми обмеження запитів, щоб контролювати швидкість API-запитів від клієнтів, забезпечуючи справедливе використання та запобігаючи зловживанню.
7.

Пагінація (Pagination)

Пагінація дозволяє API ефективно обробляти великі набори даних, розбиваючи результати на менші, зручніші для обробки частини.

Приклад:

from rest_framework.pagination import PageNumberPagination  

class CustomPagination(PageNumberPagination):  
 page_size = 10

Як працює Django Rest Framework за лаштунками

  1. Обробка запиту Коли запит досягає точки доступу DRF, фреймворк обробляє його через кілька етапів:
  2. Серіалізація Після того як вид обробить дані, серіалізатори перетворюють їх у формат JSON (або інший формат), щоб відправити клієнту.
  3. Відповідь DRF форматує відповідь, застосовуючи додаткові функції, такі як пагінація або обмеження запитів, і надсилає її клієнту.
  4. Проміжне програмне забезпечення (Middleware) та сигнали (Signals) Проміжне програмне забезпечення та система сигналів Django часто взаємодіють з DRF для обробки таких задач, як аутентифікація, кешування та журналювання.

Структура файлів проекту Django Rest Framework

Типова структура проекту DRF виглядає наступним чином:

myproject/  
├── manage.py  
├── myproject/  
│ ├── __init__.py  
│ ├── settings.py  
│ ├── urls.py  
│ ├── wsgi.py  
├── myapp/  
 ├── migrations/  
 │ ├── __init__.py  
 ├── __init__.py  
 ├── admin.py  
 ├── apps.py  
 ├── models.py  
 ├── serializers.py  
 ├── tests.py  
 ├── urls.py  
 ├── views.py
  • models.py: Визначає моделі бази даних.
  • serializers.py: Відповідає за серіалізацію даних та перевірку.
  • views.py: Містить логіку API.
  • urls.py: Відображає точки доступу API на відповідні види.
  • tests.py: Включає тестові кейси для вашого API.

Досить теорії, переходимо до практики.

Спочатку перевірте версію Python у вашій операційній системі.

python -V

Якщо виводиться таке:

Python 3.12

То Python вже встановлений. Якщо ні, ви можете скористатися інструкціями для встановлення Python на Ubuntu.

Оновіть пакети:

sudo apt update && sudo apt upgrade -y

Встановіть необхідні пакети:

sudo apt install software-properties-common -y

Додайте ppa до менеджера пакетів apt:

sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update

Тепер встановіть Python:

sudo apt install python3.12

Встановіть менеджер пакетів pip:

curl -sS https://bootstrap.pypa.io/get-pip.py | sudo python

Потім перевірте версію Python ще раз:

python -V

Тепер ви повинні побачити версію Python.

Python 3.12

Тепер переходимо до використання Django. Створіть нову папку для кореня проекту.

mkdir pawnshop-project  
cd pawnshop-project

Встановіть версію Django 4.2.18:

pip install Django==4.2.18

Створіть проект:

django-admin startproject pawnshop

Ви можете побачити корінь проекту:

pawnshop/  
├── manage.py  
├── pawnshop/  
│ ├── __init__.py  
│ ├── settings.py  
│ ├── urls.py  
│ ├── wsgi.py

Запустимо Django проект:

cd pawnshop  
python manage.py runserver 8000

Перейдіть за адресою 127.0.0.1:8000 і ви побачите сторінку привітання Django!

pic

Чудово! Ви зробили це! 🙂

Тепер давайте розглянемо детальніше. Ви можете знайти опцію налагодження в файлі settings.py.

DEBUG = True

Якщо ви запускаєте проект лише локально для розробки, немає жодної шкоди в тому, щоб залишити це значення. Якщо ж ви переходите до продакшн середовища, змініть опцію налагодження на "False".

DEBUG = False

Якщо з'являється помилка:

CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False.

Тоді потрібно налаштувати параметр дозволених хостів.

ALLOWED_HOSTS = ['127.0.0.1']

Після цього перевірте веб-сторінку ще раз, і ви побачите сторінку Bad Request (400), що є нормальною. Не переживайте! Коли ви завершите систему REST, все буде гаразд.

Тепер можемо перейти в режим DEBUG = False.

Давайте розглянемо інші налаштування в файлі settings.py.

Apps

INSTALLED_APPS = [  
 'django.contrib.admin',  
 'django.contrib.auth',  
 'django.contrib.contenttypes',  
 'django.contrib.sessions',  
 'django.contrib.messages',  
 'django.contrib.staticfiles',  
]  
...

Тут вказані додатки, які встановлені у вашому проекті. Наразі в INSTALLED_APPS є лише вбудовані додатки. Після того як ми створимо новий додаток, необхідно буде додати його сюди.

Проміжне програмне забезпечення (Middleware)

MIDDLEWARE = [  
 'django.middleware.security.SecurityMiddleware',  
 'django.contrib.sessions.middleware.SessionMiddleware',  
 'django.middleware.common.CommonMiddleware',  
 'django.middleware.csrf.CsrfViewMiddleware',  
 'django.contrib.auth.middleware.AuthenticationMiddleware',  
 'django.contrib.messages.middleware.MessageMiddleware',  
 'django.middleware.clickjacking.XFrameOptionsMiddleware',  
]  
...

У Django проміжне програмне забезпечення (Middleware) — це легкий, налаштовуваний шар, який розташовується між веб-сервером і вашим Django-додатком. Воно обробляє запити та відповіді глобально для вашого додатку, даючи змогу змінювати їх до того, як вони потраплять до виду (view), або після того, як вид їх обробить. Проміжне програмне забезпечення є необхідним інструментом у Django для управління різними аспектами обробки запитів та відповідей.

Основні характеристики проміжного програмного забезпечення

  1. Глобальна обробка запитів/відповідей
    Проміжне програмне забезпечення діє глобально, впливаючи на всі запити та відповіді, що проходять через додаток.
  2. Ланцюжок
    Кілька класів проміжного програмного забезпечення можуть бути послідовно накладені, кожен з яких обробляє запит/відповідь у порядку їх виклику.
  3. Налаштовуваність
    Ви можете написати своє власне проміжне програмне забезпечення для додавання або зміни функціональності в проекті.

Типові випадки використання

  1. Управління сесіями
    Проміжне програмне забезпечення обробляє сесійні куки та прив'язує їх до даних, специфічних для користувача.

2. Аутентифікація
Проміжне програмне забезпечення виконує аутентифікацію користувачів і додає інформацію про користувача до запитів.

3. Захист від CSRF
Django включає проміжне програмне забезпечення для захисту від підробки запитів між сайтами (CSRF).

4. Стиснення контенту
Проміжне програмне забезпечення може стискати відповіді, щоб зменшити використання пропускної здатності.

5. Журналювання та налагодження
Проміжне програмне забезпечення може журналювати запити та відповіді для цілей налагодження.

Як працює проміжне програмне забезпечення

Проміжне програмне забезпечення обробляє кожен запит та кожну відповідь через наступний процес:

  1. Етап запиту:
  • До того, як запит потрапить до виду, проміжне програмне забезпечення може змінити або відхилити його.

2. Обробка виду:

  • Запит передається відповідному виду для обробки.

3. Етап відповіді:

  • Після того, як вид поверне відповідь, проміжне програмне забезпечення може змінити її або завершити обробку.

База даних

DATABASES = {  
 'default': {  
 'ENGINE': 'django.db.backends.sqlite3',  
 'NAME': BASE_DIR / 'db.sqlite3',  
 }  
}  
...

Ви бачите розділ бази даних у файлі settings.py. Спочатку Django використовує базу даних sqlite. Ми будемо використовувати налаштування для Postgresql на наступних етапах проекту. Зараз цілком достатньо використовувати можливості Django.

Часовий пояс і мовний код

LANGUAGE_CODE = 'en-us'  

TIME_ZONE = 'UTC'  
...

Ви можете налаштувати часовий пояс за допомогою цих параметрів. Ось тут ви знайдете список допустимих часових поясів, які можна використовувати так:

LANGUAGE_CODE = 'tr-TR'  

TIME_ZONE = 'Europe/Istanbul'  
...

Чудово, що ви залишаєтесь терплячими!

Створимо перший додаток:

python manage.py startapp products

Після цього структура кореневого каталогу виглядатиме так:

pawnshop/  
├── manage.py  
├── pawnshop/  
│ ├── __init__.py  
│ ├── settings.py  
│ ├── urls.py  
│ ├── wsgi.py  
├── products/  
 ├── migrations/  
 │ ├── __init__.py  
 ├── __init__.py  
 ├── admin.py  
 ├── apps.py  
 ├── models.py  
 ├── serializers.py  
 ├── tests.py  
 ├── urls.py  
 ├── views.py

Додайте ім'я додатку у файл settings.py.

INSTALLED_APPS = [  
 'django.contrib.admin',  
 'django.contrib.auth',  
 'django.contrib.contenttypes',  
 'django.contrib.sessions',  
 'django.contrib.messages',  
 'django.contrib.staticfiles',  
 'products.apps.ProductsConfig' # Це наш новий додаток.  
]

Тепер час обробити міграції.

У Django makemigrations — це команда, яка використовується для створення файлів міграцій на основі змін, які ви внесли у свої моделі. Міграції — це спосіб застосування змін схеми бази даних, таких як додавання або модифікація полів, створення нових таблиць чи видалення старих. Коли ви запускаєте makemigrations, Django перевіряє зміни в ваших моделях (у файлах models.py) і генерує файли міграцій, які описують ці зміни.

Ці файли міграцій можна пізніше застосувати до вашої бази даних за допомогою команди migrate, яка фактично виконує зміни та оновлює схему бази даних відповідно. По суті, makemigrations готує "інструкції" для того, як оновити структуру бази даних, але безпосередньо не змінює базу даних — це відбувається, коли ви запускаєте migrate.

python manage.py makemigrations   
python manage.py migrate

Ви побачите екран:

Operations to perform:  
 Apply all migrations: admin, auth, contenttypes, sessions  
Running migrations:  
 Applying contenttypes.0001_initial... OK  
 Applying auth.0001_initial... OK  
 Applying admin.0001_initial... OK  
 Applying admin.0002_logentry_remove_auto_add... OK  
 Applying admin.0003_logentry_add_action_flag_choices... OK  
 Applying contenttypes.0002_remove_content_type_name... OK  
 Applying auth.0002_alter_permission_name_max_length... OK  
 Applying auth.0003_alter_user_email_max_length... OK  
 Applying auth.0004_alter_user_username_opts... OK  
 Applying auth.0005_alter_user_last_login_null... OK  
 Applying auth.0006_require_contenttypes_0002... OK  
 Applying auth.0007_alter_validators_add_error_messages... OK  
 Applying auth.0008_alter_user_username_max_length... OK  
 Applying auth.0009_alter_user_last_name_max_length... OK  
 Applying auth.0010_alter_group_name_max_length... OK  
 Applying auth.0011_update_proxy_permissions... OK  
 Applying auth.0012_alter_user_first_name_max_length... OK  
 Applying sessions.0001_initial... OK

Тепер ви можете побачити файл бази даних db.sqlite3, який був створений після цієї команди. Кожна модель створює нові таблиці в ньому. Тепер перші кроки завершено. Наступний етап — Django Restframework!

Django Restframework

Django Rest Framework (DRF) — це потужний і гнучкий набір інструментів для створення Web API в Django. Він спрощує процес створення RESTful API, які зазвичай використовуються для обробки запитів і відповідей у веб-додатках. Більше інформації можна знайти на офіційному сайті.

Встановимо DRF:

pip install djangorestframework  
pip install markdown # Підтримка Markdown для переглядового API.

## Додаткові налаштування

pip install django-filter # Підтримка фільтрації
pip install djangorestframework-simplejwt
pip install drf-spectacular
```

Створіть файл .env у кореневій папці проєкту, як показано нижче.

.env

API_TITLE=Pawnshop  
API_DESCRIPTION=Pawnshop Products  
API_VERSION=v0.0.0  
SERVE_PUBLIC=PawnshopTest

Остання структура:

pawnshop/  
├── .env # Новий  
├── manage.py  
├── pawnshop/  
│ ├── __init__.py  
│ ├── settings.py  
│ ├── urls.py  
│ ├── wsgi.py  
├── products/  
 ├── migrations/  
 │ ├── __init__.py  
 ├── __init__.py  
 ├── admin.py  
 ├── apps.py  
 ├── models.py  
 ├── serializers.py  
 ├── tests.py  
 ├── urls.py  
 ├── views.py

Додайте наступні імпорти в settings.py.

import os  
from datetime import timedelta  
import dotenv  

dotenv.load_dotenv()

Додайте 'restframework_' до INSTALLEDAPPS у **settings.py_**.

INSTALLED_APPS = [  
 'django.contrib.admin',  
 'django.contrib.auth',  
 'django.contrib.contenttypes',  
 'django.contrib.sessions',  
 'django.contrib.messages',  
 'django.contrib.staticfiles',  
 'products.apps.ProductsConfig',  
 'rest_framework', # Новий  
 'drf_spectacular' # Новий  
]  
...

Надаю вам майже повний набір налаштувань для drf, додайте їх у settings.py.

REST_FRAMEWORK = {  
 "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",  
 "DEFAULT_AUTHENTICATION_CLASSES": [  
 "rest_framework.authentication.BasicAuthentication",  
 "rest_framework_simplejwt.authentication.JWTAuthentication",  
 "rest_framework.authentication.TokenAuthentication",  
 ],  
 "DEFAULT_PERMISSION_CLASSES": ["rest_framework.permissions.IsAuthenticated"],  
 "DEFAULT_RENDERER_CLASSES": ("rest_framework.renderers.JSONRenderer",),  
 "DEFAULT_FILTER_BACKENDS": [  
 "rest_framework.filters.OrderingFilter",  
 "django_filters.rest_framework.DjangoFilterBackend",  
 ],  
 "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",  
 "PAGE_SIZE": 24,  
 "DEFAULT_THROTTLE_CLASSES": ["rest_framework.throttling.ScopedRateThrottle"],  
 "DEFAULT_THROTTLE_RATES": {  
 "dj_rest_auth": "10000000000000/day",  
 "anon": "2000/day",  
 },  
 "TEST_REQUEST_DEFAULT_FORMAT": "json",  
}  

SPECTACULAR_SETTINGS = {  
 "TITLE": os.environ.get("API_TITLE"),  
 "DESCRIPTION": os.environ.get("API_DESCRIPTION"),  
 "VERSION": os.environ.get("API_VERSION"),  
 "SERVE_PUBLIC": os.environ.get("SERVE_PUBLIC"),  
 "COMPONENT_NO_READ_ONLY_REQUIRED": True,  
}  

SIMPLE_JWT = {  
 "REFRESH_TOKEN_LIFETIME": timedelta(days=15),  
 "ROTATE_REFRESH_TOKENS": True,  
}  
...

Додайте нові налаштування до urls.py.

"""  
Конфігурація URL для проєкту pawnshop.  

Список `urlpatterns` маршрутизує URL до представлень. Для отримання додаткової інформації, будь ласка, дивіться:  
 https://docs.djangoproject.com/en/4.2/topics/http/urls/  
Приклад:  
Функціональні представлення  
 1. Додайте імпорт: from my_app import views  
 2. Додайте URL до urlpatterns: path('', views.home, name='home')  
Класові представлення  
 1. Додайте імпорт: from other_app.views import Home  
 2. Додайте URL до urlpatterns: path('', Home.as_view(), name='home')  
Включення іншої конфігурації URL  
 1. Імпортуйте функцію include(): from django.urls import include, path  
 2.
## Додавання URL в urlpatterns

Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from restframework import routers
from pawnshop import views
from drf
spectacular.views import (
SpectacularAPIView,
SpectacularRedocView,
SpectacularSwaggerView,
)

router = routers.DefaultRouter()
router.register(r"users", views.UserViewSet)
router.register(r"groups", views.GroupViewSet)

urlpatterns = [
path('admin/', admin.site.urls),
path('api-auth/', include('restframework.urls')),
path("api/schema/", SpectacularAPIView.as
view(), name="schema"),
path(
"api/schema/redoc/",
SpectacularRedocView.asview(urlname="schema"),
name="redoc",
),
path(
"docs/",
SpectacularSwaggerView.asview(urlname="schema", title="source"),
name="docs-ui",
)

]
```

Створіть views.py у проєкті pawnshop і додайте код там.

from django.contrib.auth.models import Group, User  
from rest_framework import permissions, viewsets  
from pawnshop.serializers import GroupSerializer, UserSerializer  


class UserViewSet(viewsets.ModelViewSet):  
 """  
 API endpoint that allows users to be viewed or edited.  
 """  

 queryset = User.objects.all().order_by("-date_joined")  

 serializer_class = UserSerializer  

 permission_classes = [permissions.IsAuthenticated]  


class GroupViewSet(viewsets.ModelViewSet):  
 """  
 API endpoint that allows groups to be viewed or edited.  
 """  

 queryset = Group.objects.all()  
 serializer_class = GroupSerializer  
 permission_classes = [permissions.IsAuthenticated]

Створіть serializers.py у проєкті pawnshop.

from django.contrib.auth.models import Group, User  
from rest_framework import serializers  


class UserSerializer(serializers.HyperlinkedModelSerializer):  
 class Meta:  
 model = User  
 fields = ["url", "username", "email", "groups"]  


class GroupSerializer(serializers.HyperlinkedModelSerializer):  
 class Meta:  
 model = Group  
 fields = ["url", "name"]

Коренева структура проєкту повинна бути такою:

pawnshop/  
├── .env # Новий  
├── manage.py  
├── pawnshop/  
│ ├── __init__.py  
│ ├── views.py # Новий  
│ ├── serializers.py # Новий  
│ ├── settings.py  
│ ├── urls.py  
│ ├── wsgi.py  
├── products/  
 ├── migrations/  
 │ ├── __init__.py  
 ├── __init__.py  
 ├── admin.py  
 ├── apps.py  
 ├── models.py  
 ├── serializers.py  
 ├── tests.py  
 ├── urls.py  
 ├── views.py

Створіть нового суперкористувача для Django:

python manage.py createsuperuser
Username (leave blank to use 'doctor'): admin  
Email address: [email protected]  
Password: admin  
Password (again): admin  
The password is too similar to the username.  
This password is too short. It must contain at least 8 characters.  
This password is too common.  
Bypass password validation and create user anyway? [y/N]: y  
Superuser created successfully.

Потім запустіть сервер знову.

python manage.py runserver 8000

Якщо з'являється помилка:

Error: That port is already in use.

Очистіть порт і запустіть сервер знову, ви можете використовувати цю команду, вона корисна кожного разу, коли ви хочете запустити Django.

kill -9 $(lsof -t -i:8000) || echo "Port has already cleared" && python manage.py runserver 8000

Перейдіть за посиланням http://127.0.0.1:8000/docs/.

pic

Натискайте кнопку Authorize:

pic

Увійдіть, використовуючи ім'я користувача та пароль, який ми створили за допомогою “python manage.py createsuperuser” раніше.

pic

Спробуйте отримати "users” натискаючи кнопку “Try it out”.

pic

Тепер ви можете створювати нових користувачів або групи через цю сторінку.

Також ми можемо використовувати адміністративну сторінку для керування користувачами та групами.

pic

Перший проєкт на Django Rest Framework готовий! Гарна робота! 🙂

Висновок

Ми створили проєкт Django з нуля. Додали до цього проєкту додаток під назвою “products”. У файлі налаштувань ми зробили необхідні конфігурації для Rest Framework та OpenAPI. Створивши нові файли для представлень (views) та серіалізаторів (serializers), ми створили API-ендпоїнти для користувачів та груп. Ми зрозуміли, як керувати ними через сторінку OpenAPI та адміністративну панель.

У наступному уроці ми зробимо поліпшення для додатка “products”. Залишайтеся з нами!

Перекладено з: DRF Part 1: Mastering Django Rest Framework: The Ultimate Guide for Professional From Scratch to Deployment

Leave a Reply

Your email address will not be published. Required fields are marked *