Django REST Framework создание API: Урок 4, CRUD запросы на основе классов
avatar
7 | (offline)
❤️‍🔥Notehunter Developer
Добавлено:
Категория: Руководства «Django»
Комментариев: 0

В уроке 4 по созданию API на Django REST Framework, мы рассмотрим создание запросов (добавления, получения, изменения, удаления) для нашей модели Статьи на основе классов.

В прошлом уроке мы рассмотрели два запроса основанных на функциях: запрос GET и POST: Django REST Framework создание API: Урок: 3, сериализация данных на основе функций

Перейдем к созданию запросов, создавать мы все также будет во views/articles.py

Запрос на получение статей (ListAPIView):

modules/blog/views/articles.py

from modules.blog.models import Article
from modules.blog.serializers import ArticleSerializer
from rest_framework import generics


class ArticleListAPIView(generics.ListAPIView):
    """
    Контроллер для просмотра списка статей (Только GET)
    """
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

Пояснение:

  • queryset - передаем список статей (Article.objects.all())
  • serializer_class - передаем наш сериалайзер, что создали в третьем уроке для модели статьи.
  • Также есть дополнительные методы, о них можете почитать в официальной документации: Generic views - Django REST framework

Необязательно для тех, кто делает все в файле views.py. Добавлю импорты в __init__.py:

modules/blog/views/__init__.py

from modules.blog.views.articles import ArticleListAPIView

__all__ = '__all__'

Добавлю обработку нашего контроллера в urls.py

modules/blog/urls.py

from django.urls import path
from modules.blog import views

urlpatterns = [
    path('articles/', views.ArticleListAPIView.as_view(), name='api_articles_list'),
]

Проверю запрос на получение списка статей, отправив запрос на страницу: http://127.0.0.1:8000/api/articles/

Запрос на добавление статьи (CreateAPIView):

from modules.blog.models import Article
from modules.blog.serializers import ArticleSerializer
from rest_framework import generics
from django.template.defaultfilters import slugify


class ArticleCreateAPIView(generics.CreateAPIView):
    """
    Контроллер для добавления статьи (Только POST)
    """
    serializer_class = ArticleSerializer

    def perform_create(self, serializer):
        """
        Метод создания статьи в БД
        """
        # Если не задан слаг, генерируем его из заголовка
        slug = serializer.validated_data.get('slug')
        if slug is None:
            slug = slugify(serializer.validated_data.get('title'))
            serializer.save(slug=slug)
        print(serializer.validated_data)
        return super().perform_create(serializer)

Пояснение:

  • serializer_class - передаем наш сериалайзер, что создали в третьем уроке для модели статьи.
  • perform_create - метод, в котором мы можем задавать различные параметры для создаваемого объекта, аналогично методу сохранения в CreateView с формами.
  • В примере perform_create показан метод генерации slug при его отсутствии с помощью слагификации заголовка.  
  • Информация из print(serializer.validated_data): OrderedDict([('title', 'My test Article'), ('short_description', 'Тестовая статья, отправленная через CreateAPIView'), ('full_description', 'Тестовая статья, отправленная через CreateAPIView'), ('category', <Category: Python>)])

Добавлю импорты в __init__.py

from modules.blog.views.articles import ArticleListAPIView, ArticleCreateAPIView

__all__ = '__all__'

Добавлю обработку нашего контроллера в urls.py

modules/blog/urls.py

from django.urls import path
from modules.blog import views

urlpatterns = [
    path('articles/', views.ArticleListAPIView.as_view(), name='api_articles_list'),
    path('articles/create/', views.ArticleCreateAPIView.as_view(), name='api_articles_create'),
]

Проверю POST запрос на создание статьи, отправив запрос на страницу: http://127.0.0.1:8000/api/articles/create/

Все отлично, отправил главную информацию в виде заголовка, описаний и категории, остальное автоматически отработало в сериализаторе и в нашей модели.

Запрос на получение одного экземпляра статьи (RetrieveAPIView):

modules/blog/views/articles.py

from modules.blog.models import Article
from modules.blog.serializers import ArticleSerializer
from rest_framework import generics


class ArticleRetrieveAPIView(generics.RetrieveAPIView):
    """
    Контроллер для просмотра статьи (Только GET)
    """
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    lookup_field = 'slug'

Пояснение:

  • queryset - передаем список статей (Article.objects.all())
  • serializer_class - передаем наш сериалайзер, что создали в третьем уроке для модели статьи.
  • lookup_field - поле, по которому будет получаться статья. Я передаю slug.

Добавлю импорты в __init__.py:

modules/blog/views/__init__.py

from modules.blog.views.articles import ArticleListAPIView, ArticleCreateAPIView, ArticleRetrieveAPIView

__all__ = '__all__'

Добавлю обработку нашего контроллера в urls.py

modules/blog/urls.py

from django.urls import path
from modules.blog import views

urlpatterns = [
    path('articles/', views.ArticleListAPIView.as_view(), name='api_articles_list'),
    path('articles/create/', views.ArticleCreateAPIView.as_view(), name='api_articles_create'),
    path('articles/<str:slug>/', views.ArticleRetrieveAPIView.as_view(), name='api_articles_detail'),
]

Проверю GET запрос на получение одной статьи, отправив запрос на страницу со статьей созданной при запросе CreateAPIView: http://127.0.0.1:8000/api/articles/my-test-article/

Отлично, все работает. Теперь перейдем к запросу для изменения статьи.

Запрос на редактирование статьи (UpdateAPIView):

modules/blog/views/articles.py

from modules.blog.models import Article
from modules.blog.serializers import ArticleSerializer
from rest_framework import generics


class ArticleUpdateAPIView(generics.UpdateAPIView):
    """
    Контроллер для редактирования статьи (Только PUT)
    """
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    lookup_field = 'slug'

    def perform_update(self, serializer):
        """
        Метод обновления статьи в БД
        """
        instance = serializer.save()
        print(instance)
        return super().perform_update(serializer)

Пояснение:

  • queryset - передаем список статей (Article.objects.all())
  • serializer_class - передаем наш сериалайзер, что создали в третьем уроке для модели статьи.
  • lookup_field - поле, по которому будет получаться статья. Я передаю slug.
  • perform_update - метод, в котором мы можем управлять параметрами объекта.

Добавлю импорты в __init__.py:

modules/blog/views/__init__.py

from modules.blog.views.articles import ArticleListAPIView, ArticleCreateAPIView, ArticleRetrieveAPIView, ArticleUpdateAPIView

__all__ = '__all__'

Добавлю обработку нашего контроллера в urls.py

modules/blog/urls.py

from django.urls import path
from modules.blog import views

urlpatterns = [
    path('articles/', views.ArticleListAPIView.as_view(), name='api_articles_list'),
    path('articles/create/', views.ArticleCreateAPIView.as_view(), name='api_articles_create'),
    path('articles/<str:slug>/', views.ArticleRetrieveAPIView.as_view(), name='api_articles_detail'),
    path('articles/<str:slug>/update/', views.ArticleUpdateAPIView.as_view(), name='api_articles_detail'),
]

Проверю PUT запрос на редактирование одной статьи, отправив запрос на страницу со статьей созданной при запросе CreateAPIView: http://127.0.0.1:8000/api/articles/my-test-article/update/

На втором скриншоте как Вы видите, недоступен GET запрос, но это мы исправим уже в другом уроке, где рассмотрим другие смешанные виды контроллеров на основе классов.

И перейдем к запросу на удаление статьи (DestroyAPIView)

modules/blog/views/articles.py

from modules.blog.models import Article
from modules.blog.serializers import ArticleSerializer
from rest_framework import generics


class ArticleDestroyAPIView(generics.DestroyAPIView):
    """
    Контроллер для удаления статьи (Только DELETE)
    """
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    lookup_field = 'slug'

Пояснение:

  • queryset - передаем список статей (Article.objects.all())
  • serializer_class - передаем наш сериалайзер, что создали в третьем уроке для модели статьи.
  • lookup_field - поле, по которому будет получаться статья. Я передаю slug.

Добавлю импорты в __init__.py:

modules/blog/views/__init__.py

from modules.blog.views.articles import ArticleListAPIView, ArticleCreateAPIView, ArticleRetrieveAPIView, ArticleUpdateAPIView, ArticleDestroyAPIView

__all__ = '__all__'

Добавлю обработку нашего контроллера в urls.py

modules/blog/urls.py

from django.urls import path
from modules.blog import views

urlpatterns = [
    path('articles/', views.ArticleListAPIView.as_view(), name='api_articles_list'),
    path('articles/create/', views.ArticleCreateAPIView.as_view(), name='api_articles_create'),
    path('articles/<str:slug>/', views.ArticleRetrieveAPIView.as_view(), name='api_articles_detail'),
    path('articles/<str:slug>/update/', views.ArticleUpdateAPIView.as_view(), name='api_articles_detail'),
    path('articles/<str:slug>/delete/', views.ArticleDestroyAPIView.as_view(), name='api_articles_delete'),
]

Проверю DELETE запрос на удаление одной статьи, отправив запрос на страницу со статьей созданной при запросе CreateAPIView: http://127.0.0.1:8000/api/articles/my-test-article/delete/

И как видите, на скриншоте выше, статья удалилась со статусом 204.

Проверим весь список:

Отлично. Мы рассмотрели основные CRUD запросы в DRF, но это ещё не все. В следующем уроке мы рассмотрим более интересные контроллеры, которые позволят одновременно как получать что-то, так и сразу редактировать при отправке разных запросов.

Теги записи: Django, Django REST Framework, API, DRF,
Комментарии к статье 0
Комментариев нет
Форма добавления комментария (необходима регистрация)