LoginSignup
3
3

DjangoでSwaggerUIを使おう!設定方法を徹底解説

Last updated at Posted at 2022-09-14

はじめに

今回はDjangoでもSwaggerUIを使えるようにする方法について説明したいと思います

前提

  • Djangoのプロジェクトを作成済み
  • Djangoのアクセスするポート番号は8000を使用

DjangoでもSwaggerUIを使おう!

  • ローカル上で使用するとき
pip install drf-spectacular
  • requirements.txtを使用するとき
requirements.txt
drf-spectacular==0.23.1
  • poetryを使用するとき
terminal
poetry add drf-spectacular 

各種設定

プロジェクト配下にある

  • settings.py
  • urls.py

に以下を記述します

settings.py

settings.py
INSTALLED_APPS = [
    "rest_framework",
    # 先ほどインストールしたdrf_spectacularを記述
    "drf_spectacular",
]

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

REST_FRAMEWORK = {
    'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}

SPECTACULAR_SETTINGS = {
    'TITLE': 'プロジェクト名',
    'DESCRIPTION': '詳細',
    'VERSION': '1.0.0',
    # api/schemaを表示しない
    'SERVE_INCLUDE_SCHEMA': False,
}

urls.py

urls.py
from django.urls import path

from drf_spectacular.views import (
    SpectacularAPIView,
    SpectacularRedocView,
    SpectacularSwaggerView,
)

urlpatterns = [
    path("admin/", admin.site.urls),
    # 127.0.0.1/8000/api/schema にアクセスするとテキストファイルをダウンロードできます
    path("api/schema/", SpectacularAPIView.as_view(), name="schema"),
    # SwaggerUIの設定
    # 今回は127.0.0.1/8000/api/docs にアクセスするとSwaggerUIが表示されるよう設定します
    path(
        "api/docs/",
        SpectacularSwaggerView.as_view(url_name="schema"),
        name="swagger-ui",
    ),
    # Redocの設定
    # 今回は127.0.0.1/8000/api/redoc にアクセスするとRedocが表示されるよう設定します
    path(
        "api/redoc/",
        SpectacularRedocView.as_view(url_name="schema"),
        name="redoc",
    ),
]

http://127.0.0.1/api/docs へアクセスした際にSwaggerUIが出たら成功です
スクリーンショット 2022-10-09 8.29.53.png

http://127.0.0.1/api/redoc にアクセスするとRedocも表示されます
スクリーンショット 2022-10-09 8.33.14.png

ModelやViewに何も記述していない場合は以下のように
No operations defined in spec!
と表示されます

http://127.0.0.1/api/redoc も同様にModelやViewに何も記述していない場合は以下のように表示されます

一度Swaggerの設定をすると

  • ローカル上
  • Docker

ともにホットリロードされるので変更のたびにローカル上でrunserverし直したり、コンテナを手動でrestartする必要がないのでとても便利です

extend_schema

また、以下のようにextend_schemaを使うことでSwaggerを使用する際にrequest内のパラメータを予め指定したり200、400の時のレスポンス例を作成することもできます

views.py
from application.models import User
from application.serializers.user import LoginSerializer, UserSerializer
from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponse, JsonResponse
from project.settings import DEBUG
from drf_spectacular.utils import OpenApiExample, OpenApiResponse, extend_schema
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.permissions import AllowAny
from rest_framework.viewsets import ModelViewSet, ViewSet


class UserViewSet(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer


class LoginViewSet(ViewSet):
    serializer_class = LoginSerializer
    permission_classes = [AllowAny]

    @action(detail=False, methods=["POST"])
    def login(self, request):
        """ユーザのログイン"""
        serializer = LoginSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        employee_number = serializer.validated_data.get("employee_number")
        password = serializer.validated_data.get("password")
        user = authenticate(employee_number=employee_number, password=password)
        if not user:
            return JsonResponse(
                data={"msg": "社員番号またはパスワードが間違っています"},
                status=status.HTTP_400_BAD_REQUEST,
            )
        else:
            login(request, user)
            return JsonResponse(data={"role": user.Role(user.role).name})

    @action(methods=["POST"], detail=False)
    def logout(self, request):
        """ユーザのログアウト"""
        logout(request)
        return HttpResponse()

    
    extend_schema(
        request=LoginSerializer,
        examples=[
            OpenApiExample(
                "ログイン",
                summary="ログインAPIのリクエスト",
                value={
                    "employee_number": "00000001",
                    "password": "test",
                },
                request_only=True,
                response_only=False,
                description="システムユーザーのログイン",
            )
        ],
        responses=OpenApiResponse(
            status.HTTP_200_OK,
            description="ログインが成功した場合",
            examples=[
                OpenApiExample(
                    "login",
                    summary={
                        "ログイン成功時のレスポンス",
                    },
                    value={
                        "role": User.Role.MANAGEMENT
                    },
                    request_only=False,
                    response_only=True,
                )
            ],
        ),
        summary="システムユーザーのログイン",
    )(LoginViewSet.login)
    
    extend_schema(
        request=None,
        responses={
            status.HTTP_200_OK: OpenApiResponse(
                description="ログアウトに成功しました",
            ),
        },
        summary="システムユーザのログアウト",
    )(LoginViewSet.logout)

スクリーンショット 2024-01-09 14.09.29.png

スクリーンショット 2024-01-09 14.09.51.png

drf-spectacularで自動生成したAPIドキュメントをymlに出力するには

下記のコマンドを実行するとymlファイルに出力できます

python manage.py spectacular --file schema.yml

ymlファイルに出力することができると、例えば下記のようにGitHub Pagesにアップロードできます

最後に

Swagger最高!

参考文献

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3