本記事の対象者
- DjangoでサクッとAPIを作成したい方
※今回はシンプルなCRUDのRESTAPIを作成していきますので複雑なカスタマイズ方法などは記載しません。
ローカルで用意する環境
- Django3.1
下記がDjango環境構築をまとめた記事になりますのでまだの方はこちらからご確認ください。
必要ライブラリのインストール
pipコマンドを実行してインストールします。
djangorestframework、django-filter、drf-yasgのインストールを実行します。
$ pip install djangorestframework
$ pip install django-filter
$ pip install drf-yasg
dockerで環境構築している方はコンテナ内で実行してください。私のブログの記事通りdockerで環境構築した方はrequirements.txtに上記ライブラリを記述してコンテナをビルドしなおす方法でもOKです。docker環境の場合、コンテナをビルドしなおすとrequirements.txtに記載しておかないと一度インストールしたライブラリも再インストールしなおす必要があるため最初からrequirements.txtに記述したほうが良いと思います。
Djangoに新規アプリケーションを作成
manageコマンドをコンソールで実行します。
$ python manage.py startapp my_api
成功するとDjangoディレクトリ直下にmy_apiというディレクトリが作成されてます。
モデルの作成
RESTAPI用のモデルを作成していきます。今回は下記のようなモデルを作成したいと思います。
ちなみにこのAPIを使って簡単なTodoアプリを作る想定です。
まずは先ほど作成したmy_api直下にmodelsディレクトリを作成します。
modelsディレクトリ直下に下記3ファイルを作成します。
- __init__.py
- base_model.py
- task.py
メインのmodelの中身はtask.pyに記載します。base_modelはどのmodelでも共通で追加する作成日時などを記述しています。
# __init__.py from .base_model import BaseModel from .task import Task
# base_model.py from django.db import models class BaseModel(models.Model): """ 全model共通のフィールドを記述 """ class Meta: abstract = True created_at = models.DateTimeField( verbose_name='登録日時', auto_now_add=True ) updated_at = models.DateTimeField( verbose_name='更新日時', auto_now=True )
# task.py from django.db import models from my_api.models import BaseModel from datetime import date class Task(BaseModel): class Meta: db_table = 'task' verbose_name = verbose_name_plural = 'タスク' PRIORITY_CHOICES = ( (0, '小'), (1, '中'), (2, '大'), ) todo = models.CharField( verbose_name="やること", max_length=255 ) priority = models.IntegerField( verbose_name="優先度", choices=PRIORITY_CHOICES ) complete_flag = models.BooleanField( verbose_name="完了フラグ", default=False ) def __str__(self): return self.todo
※ちなみにmy_apiディレクトリ直下にmodels.pyというファイルが作成されており、そこに複数モデルを羅列するように記述していくことがDjangoのモデル作成ではデフォルトのようです。
ですが今回は1モデルごとにファイルを切り分けられるように作成しています。今回の作成方法は正直好みですのでmodels.pyに直接記述する方法でも問題ありません。
個人的にmodelはファイル分けたほうが見やすいなと思ったのでこのような構成にしています。
settingsの修正
settings.pyを下記のように修正します。「# 追加」と書かれている箇所を追加してください。デフォルトで記述されているものを削除しないように注意してください。
# settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'my_api', # 追加 'rest_framework', # 追加 'django_filters', # 追加 'drf_yasg', # 追加 'app', # 追加 ] # 下記をすべて追加 REST_FRAMEWORK = { 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'], 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema', }
マイグレーションの実行
先ほど作成したmodelをもとにマイグレーションファイルを作成します。下記コマンドを実行してください。
$ python manage.py makemigrations
上記コマンドを実行することでmodelファイルに合わせてマイグレーションファイルが作成されます。次にマイグレーション実行します。下記コマンドを実行してください。
$ python manage.py migrate
これでDBにtaskテーブルが生成されました。
serializerの作成
my_api直下にserializersディレクトリを作成します。
その後、serializersディレクトリ直下に下記2ファイルを作成します。
- __init__.py
- task_serializer.py
# __init__.py from .task_serializer import TaskSerializer
# task_serializer.py from rest_framework import serializers from my_api.models import Task class TaskSerializer(serializers.ModelSerializer): class Meta: model = Task exclude = [ "created_at", "updated_at", ]
viewsetの作成
my_api直下にviewsetsディレクトリを作成します。その後viewsets直下に下記2ファイルを作成してください。少しだけ説明するとtask_viewset.pyのfilter_fieldsにcomplete_flagを設定しておくとGETパラメータの検索項目と使用できるようになるためです。
- __init__.py
- task_viewset.py
# __init__.py from .task_viewset import TaskViewSet
# task_viewset.py from rest_framework.viewsets import ModelViewSet from my_api.models import Task from my_api.serializers import TaskSerializer class TaskViewSet(ModelViewSet): queryset = Task.objects.all() serializer_class = TaskSerializer filter_fields = { 'complete_flag': ['exact'], }
ルーティングの修正
下記の2ファイルを修正します。app配下のurls.pyにベースのルーティングを設定しmy_apiにもurls.pyを作成し、下記のように記述を追加します。
- app/urls.py
- my_api/urls.py
# app/urls.py from django.contrib import admin from django.urls import path from django.conf.urls import url, include from my_api.urls import router from rest_framework import permissions from drf_yasg.views import get_schema_view from drf_yasg import openapi schema_view = get_schema_view( openapi.Info( title="Snippets API", default_version='v1', description="Test description", terms_of_service="https://www.google.com/policies/terms/", contact=openapi.Contact(email="contact@snippets.local"), license=openapi.License(name="BSD License"), ), public=True, permission_classes=[permissions.AllowAny], ) urlpatterns = [ path('admin', admin.site.urls), url(r'^api/', include(router.urls)), url(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), ]
# my_api/urls.py from . import views from rest_framework import routers from my_api.viewsets import TaskViewSet app_name = 'my_api' router = routers.DefaultRouter() router.register(r'tasks', TaskViewSet)
これで/api/tasksというURLでRESTAPIが使用できるようになりました。
動作確認
それではブラウ上で確認してみましょう。runserverコマンドを実行します。
$ python manage.py runserver
コマンドが成功したら下記URLにアクセスしてください。そうすると下記画面が表示されます。
このURLはGETパラメータになるためデータが存在する場合Listでデータを取得できます。
今はデータがないので作成してみます。下に入力欄があるのでそこを入力してPOSTしましょう。
その後、再度 http://127.0.0.1:8000/api/tasks/ にアクセスしてください。そうするとデータが取得できます。
SwaggerでAPI一覧を確認
今回はAPIのメソッドを限定せずに作成していますので、GET、POST、PUT、PATCH、DELETE全てが使用可能です。API一覧を確認するためにSwaggerもインストールと設定もこれまでに終わらせているので下記URLにアクセスすると画面が表示されます。
当然Swaggerからメソッドの実行も可能です。またドキュメントをSwaggerから作成することも可能ですのでその点でも非常に便利なライブラリです。DjangoでAPIを作成する際はぜひ試してみてください。
コメント