В этом посте я представлю следующие концепции, не стесняйтесь перейти к следующему сообщению, если вы уже знакомы с ними:
- Создать проект Django с Django Rest Framework
- Добавить спецификации OpenAPI для генерации документации по динамической API
- Используйте JWT (JSON Web Token) для аутентификации и авторизации
Шаг № 1 – Создайте новый проект
Начните новый проект (либо с Pycharm -> Новый проект Django или django -admin startproject restapi_article
). Я не буду покрывать основы, потому что вы всегда можете пойти в Джанго Учебник и учиться на официальной документации (которую я нахожу лучшим на момент написания этой статьи).
Как только у нас будет настроен проект Django, нам нужно установить библиотеки Python ниже (для лучшего опыта вы должны использовать Виртуальная среда ):
- Джанго
- djangorestframework
- DRF-YASG
- djangorestframework-simplejwt
Всегда хорошо соответствовать стандартам, поэтому мы должны создать Требования.txt
Файл со всеми библиотеками. Вы можете создать его, используя эту команду в папке Project Root PIP FREEZE> Требования.txt
Анкет Файл должен выглядеть так:
asgiref==3.2.10 certifi==2020.6.20 chardet==3.0.4 coreapi==2.3.3 coreschema==0.0.4 Django==3.1.1 djangorestframework==3.11.1 djangorestframework-simplejwt==4.4.0 drf-yasg==1.17.1 idna==2.10 inflection==0.5.1 itypes==1.2.0 Jinja2==2.11.2 MarkupSafe==1.1.1 packaging==20.4 PyJWT==1.7.1 pyparsing==2.4.7 pytz==2020.1 requests==2.24.0 ruamel.yaml==0.16.12 ruamel.yaml.clib==0.2.2 six==1.15.0 sqlparse==0.3.1 uritemplate==3.0.1 urllib3==1.25.10
Далее создайте приложение с командой Python3 Manage.py StartApp Restapi
Ваша структура файла после создания должна выглядеть так:
. ├── restapi │ ├── migrations │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── models.py │ ├── tests.py │ └── views.py ├── restapi_article │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── venv ├── db.sqlite3 ├── manage.py └── requirements.txt
И добавить в наш restapi_article \ settings.py
Эти три приложения
INSTALLED_APPS = [ ... 'rest_framework', 'drf_yasg', 'restapi', ]
Редактировать urls.py
Чтобы использовать root restapi.urls в качестве основных URL -адресов приложения API, мы будем иметь Localhost: 8000/Admin
Играть с административной панелью Джанго и /api/v1
Конечная точка в качестве префикса для всех URL -адресов (это действительно хороший способ версировать ваш API, как это может легко измениться в будущем)
from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('api/v1/', include('restapi.urls')), ]
Шаг 2 – Создайте модели данных
Я хочу иметь приложение для дневника, где я могу выбрать день, а затем опубликовать для себя примечание. Кроме того, я хочу иметь профиль пользователя с полем Bio, местоположением и датой рождения.
Профиль и день будут связаны как многие ко многим отношениям через модель DIRNINGDAY, где я могу опубликовать записку для данного дня (то, что я выпил и с кем, например).
Todo (Future): Создайте модель событий, где вы можете попросить некоторых людей присоединиться к вам в питье. Ему придется объединить несколько профилей/пользователей с одной датой
Мы также будем использовать сигналы Чтобы создать крючки для создания пользователей, поэтому нам нужно только создать или обновить модель профиля, а пользователь будет создан/обновляется автоматически с помощью одного запроса.
models.py
from django.contrib.auth.models import User from django.db import models from django.db.models.signals import post_save from django.dispatch import receiver class Day(models.Model): day = models.DateField() class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) bio = models.TextField(max_length=500, blank=True) location = models.CharField(max_length=30, blank=True) birth_date = models.DateField(null=True, blank=True) days = models.ManyToManyField(Day, through='DrinkingDay') class DrinkingDay(models.Model): profile = models.ForeignKey(Profile, on_delete=models.CASCADE) day = models.ForeignKey(Day, on_delete=models.CASCADE) note = models.TextField(max_length=1000, blank=True) # Use signals so our Profile model will be automatically created # or updated when we create or update User instance # https://docs.djangoproject.com/en/3.1/topics/signals/ @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) @receiver(post_save, sender=User) def save_user_profile(sender, instance, **kwargs): instance.profile.save()
Теперь давайте создадим и применяем миграции для БД, а затем создадим суперпользователь, чтобы иметь возможность войти в нашу панель администратора. Вам нужно запустить эти три команды один за другим (вы можете изменить электронную почту и имя пользователя), конечно)
python manage.py makemigrations python manage.py migrate python manage.py createsuperuser --email admin@example.com --username admin
Шаг 3 – Создать сериализаторы
Теперь нам нужно добавить сериализаторы Анкет Serializer в ярлыке – это способ создать JSON из объекта. Давайте начнем писать сериализаторы для модели пользователей и профиля (нам нужно сделать их обоих, так как это не будет работать без пользователя):
serializers.py
from django.contrib.auth.models import User from rest_framework import serializers from restapi.models import Profile class UserSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = User fields = ['url', 'username', 'email', 'groups'] class ProfileSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Profile fields = ['user', 'bio', 'location', 'birth_date', 'days']
Шаг 4 – Создать виды
Теперь, когда у нас есть сериализаторы, мы можем создавать представления в Джанго. Итак, на каждом URL мы увидим, что хотим. Давайте сделаем это для USerview и ProfileView (хотя здесь мы могли бы опустить представление пользователя, поскольку это не требуется.
Изменение views.py
(в папке API REST):
from django.contrib.auth.models import User from rest_framework import viewsets from restapi.models import Profile from restapi.serializers import ProfileSerializer, 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 class ProfileViewSet(viewsets.ModelViewSet): """ API endpoint that allows profiles to be viewed or edited. """ queryset = Profile.objects.all() serializer_class = ProfileSerializer
Шаг 5 – Зарегистрируйте маршрутизатор для просмотров
DRF позволяет нам использовать что -то, что называется маршрутизаторы Анкет Это будет обрабатывать автоматическую маршрутизацию URL для Django для нас.
Изменение urls.py
(в папке Restapi):
from django.urls import path, include from rest_framework import routers from restapi import views router = routers.DefaultRouter() router.register(r'profile', views.ProfileViewSet) router.register(r'user', views.UserViewSet) urlpatterns = [ path('api-auth/', include('rest_framework.urls', namespace='rest_framework')), path('', include(router.urls)), ]
Теперь мы можем запустить наше приложение с Python Manage.py Runserver
и пойти в http://127.0.0.1:8000/api/v1/
Чтобы увидеть, что наше приложение работает:)
Если вы создали суперпользователь, это должно автоматически создать для него профиль, поэтому переход к http://127.0.0.1:8000/api/v1/profile/1/
должен позволить вам обновить профиль суперпользователя.
Шаг 6 – Добавить документацию Swagger
Все уже хорошо, чтобы идти, нам просто нужно создать URL для демонстрации документации Swagger. Кроме того, это хорошая практика для создания Schema_View, чтобы описать наш API для других разработчиков.
Обновление urls.py
(в папке Restapi):
from django.urls import path, include, re_path from drf_yasg import openapi from drf_yasg.views import get_schema_view from rest_framework import routers, permissions from restapi import views router = routers.DefaultRouter() router.register(r'profile', views.ProfileViewSet) router.register(r'user', views.UserViewSet) schema_view = get_schema_view( openapi.Info( title="Drinking Day API", default_version='v1', description="This API allows us to keep a diary of our daily drinking", terms_of_service="https://www.scvconsultants.com", contact=openapi.Contact(email="michal@scvconsultants.com"), license=openapi.License(name="MIT License"), ), public=True, permission_classes=(permissions.AllowAny,), ) urlpatterns = [ path('api-auth/', include('rest_framework.urls', namespace='rest_framework')), path('', include(router.urls)), re_path(r'^swagger(?P\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'), path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), ]
Теперь мы должны быть в состоянии увидеть Swagger UI по адресу: http://127.0.0.1:8000/api/v1/swagger/
и .json + .yaml схема по ссылкам ниже: http://127.0.0.1:8000/api/v1/swagger.json
http://127.0.0.1:8000/api/v1/swagger.yaml
Шаг 7 – Добавьте токены JWT, чтобы ограничить доступ к модели профиля.
Во -первых, нам нужно обновить настройки.py
Чтобы добавить классы jwt auth. Я также добавляю страницу, так как это отличная практика для использования размера страницы по умолчанию для коллекций (нам не нужно отправлять все сразу, верно?).
# REST FRAMEWORK config REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 25, 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_simplejwt.authentication.JWTAuthentication', ) }
Затем нам нужно создать конечную точку для захвата и освежающего токена (как токены должны истекать из соображений безопасности). Вы можете настроить его сами с Официальная документация Анкет
Давайте добавим его в urls.py
from rest_framework_simplejwt.views import ( TokenObtainPairView, TokenRefreshView, ) urlpatterns = [ ... path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), ... ]
Теперь вы можете перейти к: http://127.0.0.1:8000/api/v1/token/
и отправьте свои учетные данные суперпользователя в качестве поста, и вы должны получить красивый рабочий токен, который вы можете расшифровать и проверить здесь и он должен декодировать на user_id, который соответствует вашим учетным данным (вероятно, будет, вероятно, 1).
Добавить теперь разрешения к нашим взглядам действительно прост, первый импорт в views.py
from rest_framework import permissions
А затем в нашем конкретном представлении (давайте используем ProfileViewSet для этого) добавить:
class ProfileViewSet(viewsets.ModelViewSet, mixins.UpdateModelMixin): ... permission_classes = [permissions.IsAuthenticatedOrReadOnly]
Теперь мы можем легко добавить пользователей, но мы не можем обновить наш профиль, если не предоставим правильный токен JWT. Весь список разрешений доступен в рамках REST документация
Далее:
- Создание CI/CD с использованием GitHub и Хероку Анкет
- Докеризация
- Интеграционные тесты для API с Pytest
Оригинал: “https://dev.to/misiekofski/create-proper-rest-api-with-django-drf-jwt-and-openapi-chp”