RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

【Python】Django REST Framework(DRF)を使ってWeb APIを自作してみる

こんにちは。d-t-kong と申します。

最近、趣味でDjangoを触っているのですが、Django のライブラリに Django Rest FrameworkというWebAPIを開発できるライブラリがあることを知りました。
これを使えばWebAPIを簡単に作成できるということなので、実際にサンプルのアプリケーションを 作ってAPIを自作してみました。
今回は、その手順やポイントなどを紹介していきたいと思います。

Python関連ブログ
tech-blog.rakus.co.jp

Django REST Frameworkとは

Django REST Framework(以下、DRF) とは、Django を使ってRESTful APIを作成するためのフレームワークです。

RESTful API とは

RESTful APIとは 、「REST」という以下の4つの原則に基づいて設計されるAPIのことを指します。

  • 統一インターフェース(HTTPメソッドの利用し、JSON形式でデータのやりとりをする)

  • アクセス可能なURLが公開されている

  • ステートレスである

  • 接続結果がHTTPステータスコードで通知されること

事前準備

では、実際にDRFAPIを作ってみたいと思います。
しかしその前に、今回使うアプリケーションを実装します。

使用環境
  • Python3 :3.10.1
  • Django:4.0.2
プロジェクト・アプリケーションを作成

まず、今回APIを作成する用のプロジェクト、アプリケーションを作成します。 プロジェクト名api_test、アプリケーション名drf_test_app という名前で作成します。

django-admin startproject api_test
cd api_test/
python3 manage.py drf_test_app
モデルを定義

次に、Modelクラスを定義します。
今回はユーザ情報を持ったUserInfoモデルをWebAPIテスト用のサンプルとして作成します。

drf_test_app/models.py

from unicodedata import category, name
from django.db import models
# ユーザ情報を格納する
class UserInfo(models.Model):
    user_name = models.CharField(verbose_name='ユーザ名',max_length=32)                         # ユーザ名
    birth_day = models.DateField(verbose_name='生年月日')                                       # 生年月日
    age = models.PositiveSmallIntegerField(verbose_name='年齢',null=True,unique=False)         # 年齢
    created_at = models.DateTimeField(verbose_name='作成日時',auto_now_add=True)                # 登録日時
    
データベースを構築

Modelを作成したら、データベースを構築します。
まず、settings.py にアプリケーションを追加します。

api_test/settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'drf_test_app',   # 追加する
]

アプリケーションを追加したら、以下のコマンドを入力してデータベースをマイグレートします。

% python3 manage.py makemigrations
% python3 manage.py migrate

マイグレートが完了したら、admin.py に以下のコードを追記します。 drf_test_app/admin.py

from django.contrib import admin
from .models import UserInfo
# 以下追記
admin.site.register(UserInfo)
管理アカウント作成

次に、管理者用のアカウントを作成します。
以下のコマンドを入力して下さい。

% python3 manage.py createsuperuser
Username (leave blank to use 'root'): [管理ユーザ名]
Email address: [メールアドレス]
Password: [パスワード]
Password (agein): [再パスワード]
Superuser created successfully.

これでDjango の管理サイトにアクセスできるはずなので、以下のコマンドから開発サーバーを立ち上げて、http://localhost:8000/adminにアクセスします。

% python3 manage.py runserver

ログイン画面に遷移できたら先ほど作成した管理ユーザのユーザ名・パスワードを入力してログインします。

管理者用サイト ログイン画面

ログイン後、先ほどマイグレートしたモデルが管理画面上に追加されていればOKです。

管理者用画面

DRFAPIを作成

アプリケーションの準備が終わったので、ここからは実際にAPIを作っていきます。

REST Framework をアプリケーションに追加

まず、pip コマンドでDRFをインストールします。

% pip install djangorestframework

インストール後、settings.py のINSTALLED_APPSにアプリケーションを追加します。

INSTALLED_APPS = [
    ・・・
    'rest_framework', # 追記
]

DRFの主要コンポーネントを作成

DRFAPIを作成する際、以下の3つのコンポーネントを定義する必要があります。

  1. Serializer

  2. ViewSets

  3. Router

1.Serializer

Serializerクラスは、データベースから取り出したモデルのオブジェクトをJSONserialize したり、ユーザから送られたJSONdeserializeするためのクラスです。
drf_test_app/serializer.pyを新規に作成し、以下を記述します。

drf_test_app/serializer.py

from dataclasses import fields
from pyexpat import model
from rest_framework import serializers
from .models import UserInfo
class UserInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserInfo
        # json で出力するフィールド
        fields = ('id','user_name', 'birth_day','age','created_at')
        
2.ViewSets

Serializerクラスを定義して、serializedeserializeができるようになったら、次は Viewクラスを定義します。DRF ではいくつかViewSetクラスが存在します。
今回はrest_framework.viewsets.ModelViewSetを継承したクラスを作成します。
ModelViewSetクラスはモデルに対してCRUD処理(新規追加、読み込み、更新、削除)を一括で作成 できるクラスです。
なお、ModelViewSet以外にはCRUD機能のうち、特定の機能のみを提供するGenericViewなどがあります。

参考:Django REST framework 公式ドキュメント #ModelViewSet


ちなみに、ModelViewSetクラスを用いてAPIを作成した場合のCRUD機能、HTTPメソッド、URLは以下の通りとなります。

CRUD機能 HTTP メソッド URL
Read(全レコード) GET /api/userInfo
Create POST /api/userInfo
Read(単一レコード) GET /api/userInfo/(pk)
Update(一部レコード) PUT /api/userInfo/(pk)
UPDATE(全レコード) PATCH /api/userInfo/(pk)
DELETE GET /api/userInfo/(pk)

※ pk = Primary Key です。モデルで定義していない場合も自動で付与されます


drf_test_app/views.pyに以下の記述を追加します。

drf_test_app/views.py

from rest_framework import viewsets
from .models import UserInfo
from .serializer import UserInfoSerializer
class UserInfoViewSet(viewsets.ModelViewSet):
    # モデルのオブジェクトを取得
    queryset = UserInfo.objects.all()
    # シリアライザーを取得
    serializer_class = UserInfoSerializer
3.Router

DRFではAPIへのルーティングを行うためのRouterクラスを実装する必要があります。
urls.py に Router クラスをインスタンス化し、ViewSets オブジェクトをルーティングします。

api_test/urls.py

from django.contrib import admin
from django.urls import path,include
from rest_framework import routers

from drf_test_app.api_views import UserInfoViewSet
# DefaultRouter クラスのインスタンスを代入
defaultRouter = routers.DefaultRouter()
# userInfo/ にUserInfoViewSetをルーティングする
defaultRouter.register('userInfo',UserInfoViewSet)
urlpatterns = [
    path('admin/',admin.site.urls),
    # defaultRouter をinclude する
    path('api/',include(defaultRouter.urls)),
]

APIにアクセスしてみる

コンポーネントの作成が完了したら、APIにアクセスしてみましょう。
manage.py runserver でサーバーを立ち上げ、http://localhost:8000/api/userInfo にアクセスします。
以下のような画面に遷移できればルーティング成功です。

http://localhost:8000/api/userInfo APIコンソール画面

DRF ではJSONのレスポンスをブラウザ用にページで閲覧でき、GUIで各種APIの動作確認ができます。

試しに、画面下部のリクエストフォームからAPIにPOSTリクエストを送り、レコード登録を試みます。

http://localhost:8000/api/userInfo リクエストフォーム

リクエストを送信すると、APIからのHTTPレスポンスがコンソール画面に表示されます。

http://localhost:8000/api/userInfo POST メソッドのレスポンス

また、http://localhost:8000/api/userInfo/(pk)/ にアクセスすると、pk にマッピングしたレコード一件のみの情報を表示する画面に遷移できます。
また、この画面では右上のDELETEボタン、PUT、PATCHボタンが配置されているので、レコードの更新、削除を行うことができます。

http://localhost:8000/api/userInfo/2/ 単一レコードの参照

参考文献

最後に、今回の記事を書く上で参考にした文献を紹介します。

ご覧いただき、誠にありがとうございました。


  • エンジニア中途採用サイト
    ラクスでは、エンジニア・デザイナーの中途採用を積極的に行っております!
    ご興味ありましたら是非ご確認をお願いします。
    20210916153018
    https://career-recruit.rakus.co.jp/career_engineer/

  • カジュアル面談お申込みフォーム
    どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。
    以下フォームよりお申込みください。
    rakus.hubspotpagebuilder.com

  • イベント情報
    会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください! rakus.connpass.com

Copyright © RAKUS Co., Ltd. All rights reserved.