初めに
初めまして!
株式会社iimonでエンジニアをしている遠藤です。
今回はDjango及びDRFでAPIを生成する流れを理解するために、図書館の本を管理する簡単なAPIを実装できればと思います。
DRFとは
DRF(Django REST Framework)は、DjangoでRESTful APIを作成するための、サードパーティ製のDjangoのパッケージです。
そもそもRESTful APIとは、RESTの原則に沿ったAPIのことを言います。
RESTの原則とは主に
- アドレス可能性(Addressability)
- 全ての情報はURIで表現されるユニークなアドレスを持っている。
- ステートレス性(Stateless)
- HTTPメッセージの全てがリクエストを理解するための必要な情報を含んでいるため、サーバーにセッション等の状態を持たない前提で情報のやり取りを行う。
- 接続性(Connectability)
- 統一インターフェース(Uniform Interface)
- 情報の操作に、HTTPメソッド(GET, POST, PUT, DELETE等)を利用する
の4原則からなります。
RESTful APIを用いることで、バックエンドとフロントエンドとを分離することができる点が利点です。
DjangoでRESTful APIバックエンドを構築するには、自前で色々と実装する必要があるので、今回はDRFを使用していきます。
Webアプリケーションのベースとなる部分にはDjango、REST APIに特化した機能にはDRFを利用するといった使い方をします。
導入
インストール
今回は仮想環境を用いるので、先にプロジェクトとなるディレクトリを用意しておきます。
$ mkdir drf-sample
特定のプロジェクトで必要なライブラリだけを管理するために、仮想環境を作成します。 今回はvenvを用いて仮想環境を用意していきます。
pythonが入っていない場合は、まずpythonをインストールします。 https://qiita.com/koooooo/items/b21d87ffe2b56d0c589b
以下のコマンドを実行します。
$ python -m venv drf-sample
こうすることで、drf-sampleディレクトリを仮想化することができます。
drf-sampleディレクトリに移動して、ファイルが生成されていることが確認できればOKです。
$ cd drf-sample $ls bin include lib pyvenv.cfg
仮想環境を有効化します。
$ source bin/activate
$ pip install Django==4.2 $ pip install djangorestframework==3.14.0
プロジェクトを作成
drf-sampleディレクトリで以下のコマンドを実行しましょう!
$ django-admin startproject config .
そうすると、drf-sampleがプロジェクト化され、config という名前のフォルダとmanage.pyというファイルができていると思います。
drf-sampleディレクトリで以下のコマンドを実行して、開発用サーバーを起動させます。
$ python manage.py runserver
ブラウザでhttp://localhost:8000/にアクセスして確認してみましょう。
以下のような画面が見れたらOKです!
これで、APIを実装する準備が完了しました! 早速APIを作成していきましょう!
図書館の本を管理するAPI
libraryというアプリケーションを作成し、図書館にある本の貸出可能状況を管理するための、簡単なAPIを作成していきます。今回は本のタイトルと貸出可否のみを管理する簡易的な設計にします。
アプリケーションの作成
今回はlibraryという名前のアプリケーションとapiv1という名前のアプリケーションを作成していきます。
以下のコマンドを実行します。
$ python manage.py startapp library $ python manage.py startapp apiv1
設定ファイルの修正
アプリケーションが作成できたら、config/settings.pyに、インストールしたDRFと、作成したアプリケーションを追加します。
... INSTALLED_APPS = [ ... "django.contrib.staticfiles", "rest_framework", # 追加 "apiv1", # 追加 "library" # 追加 ] ...
... # 言語コードを修正 LANGUAGE_CODE = "ja" # 修正 # タイムゾーンを修正 TIME_ZONE = "Asia/Tokyo" # 修正 ...
今回は認証にDRFのcookie認証を使用するため、設定していきます。
REST_FRAMEWORK = { "DEFAULT_AUTJENTICATION_CLASS": [ "rest_framework.authentication.SessionAuthentication", ], }
モデルの作成
では、いよいよ本データを管理するためのモデルを作成していきましょう!
from django.db import models # Create your models here. class Book(models.Model): """本モデル""" title = models.CharField(verbose_name="タイトル", max_length=20) available = models.BooleanField(verbose_name="貸出可", default=True) created_at = models.DateTimeField(verbose_name="登録日", auto_now=True) # DjangoAdminでデータを表示するために設定されてたりする def __str__(self): return self.title
データベースのマイグレーションを実行します。
$ python manage.py makemigrations library $ python manage.py migrate
ちなみに、Django Adminから作成したモデルのデータにアクセスしたい場合には、admin.pyを以下のように修正します。
from django.contrib import admin from .models import Book class BookAdmin(admin.ModelAdmin): list_display = ("title", "available", "created_at") readonly_fields = ("created_at",) admin.site.register(Book, BookAdmin)
RESTful APIバックエンドを作成
apiv1アプリケーションに追加していきます。
まず、serializerファイルを作成します。
from rest_framework import serializers from library.models import Book class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = ["title", "available"]
serializerはデータを変換するためのクラスで、主に以下の2つの役割があります。
- 入力データとオブジェクトの相互変換
- 入力データのバリデーション
次に、viewファイルを修正します。
from rest_framework.viewsets import ModelViewSet from rest_framework.permissions import IsAuthenticated from library.models import Book from .serializers import BookSerializer class BookViewSet(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer # 権限のあるユーザー以外のアクセスを拒否する permission_classes = [IsAuthenticated]
DjangoはMVTモデルで、DjangoのViewはMVCモデルでいうControllerに該当します。
DRFのviewも基本的には同じです。JSON形式のリクエストオブジェクトを受け取り、JSON形式のレスポンスオブジェクトを作成する役割を担っています。
ルーティング設定
いよいよ最後の工程です!
各APIのエンドポイントを追加して、URLにアクセスできるようにしましょう。
今回は以下のURLパターンを用意します。
HTTPメソッド URL 処理 GET, POST /auth/login ログイン GET, POST /auth/logout ログアウト GET, POST /books 本の情報の取得、登録 PATCH /books/ / 本の情報の更新 まず、config/urls.pyにpathを追加します。
from django.contrib import admin from django.urls import path, include # 追加 urlpatterns = [ path("admin/", admin.site.urls), path("auth/", include("rest_framework.urls")),# 追加 # apiv1/urls.pyを読む path("", include("apiv1.urls")), # 追加 ]
apiv1アプリケーションにもurls.pyを作成します。
from django.urls import path, include from rest_framework import routers from . import views router = routers.DefaultRouter() router.register("books", views.BookViewSet) app_name = "apiv1" urlpatterns = [ path("", include(router.urls)) ]
動作確認
まず、ログインに必要なユーザーを作成します!
$ python manage.py createsuperuser
上記のコマンドを設定すると、ユーザー名、メールアドレス、パスワードの設定が求められるので、入力します。
最終的に、
Superuser created successfully.
と表示されればOKです。
ユーザーが設定できたら、まずhttp://localhost:8000にアクセスしてみましょう。
以下のような画面が表示されると思います。
apiv1/views.pyでpermission_classesを設定しているので、ログインしていない状態でhttp://localhost:8000/books/ にアクセスすると403エラーになると思います。
そこで、右上のLog inボタンを押し、先ほど作成したユーザーでログインします。
そうすると、GETとPOSTのAPIが叩けるようになったかと思います!
また、Django Adminにアクセスする場合は、http://localhost:8000/admin/にアクセスし、同様に先ほど作成したユーザーでログインします。
以上が確認できれば完了です。
今回は簡単な設計しかしていないので、ぜひ公式ドキュメントなども読んでみてください!
参考:
https://docs.djangoproject.com/ja/4.2/intro/tutorial01/
https://qiita.com/koooooo/items/b21d87ffe2b56d0c589b
https://www.amazon.co.jp/現場で使える-Django-Framework-(Django-の教科書シリーズ)-ebook/dp/B07XWL8FPM
https://www.manajob.jp/python/python-app/venv