プログラミング

Django Rest Frameworkを使ってみよう!

こんにちは、MSKです。
最近はバックエンドとフロントエンドを別々に開発することが主流になっています。
Pythonでそのような開発を行う際に使えるのがDjango Rest Frameworkです。
今回使ってみたので、紹介します。

REST API

REST API(RESTful API)はREST(Representational State Transfer)という設計原則に従うWeb APIです。
RESTは以下の原則を持っています。

  1. セッションなどの状態を持たないステートレス前提での通信
  2. 情報の操作を行う命令が定義されている(POST、GET、PUT、DELETEなど)
  3. すべての情報がユニークな構文(URLやURI)を持つ
  4. ある情報に別の情報へのリンクを含めることができる

REST APIを使うことで、Webアプリケーションのバックエンドとフロントエンドを疎結合化することができます。
疎結合化することでWebアプリケーションを小さなアプリの集まりとして構成できます。
(開発の効率化や、不具合が生じた時に改修の手間が軽減されるなどメリットがあります。)
バックエンドとフロントエンドを分けることで、フロントエンドにモダンなJSフレームワークを使えるのもメリットいえます。

環境を構築

Dajngo Rest Frameworkを試すための環境を構築します。
Pythonについての準備は以下の記事を参考にしてください。

Pythonをインストールして使ってみよう!今回はPythonのインストールからIDLEでPythonを実行するところまで解説します。 Pythonは機械学習のデファクトスタンダードになっているなど、人気のプログラミング言語ですので、インストールをしてPythonを使うための第一歩を踏み出しましょう!...

任意のフォルダを作成します。
ターミナルを開いて、このフォルダまで移動します。
次のコマンドを実行して、仮想環境の作成とDjango、Django Rest Frameworkのインストールを行います。

python3 -m venv venv
source vevn/bin/activate
pip install Django
pip install djangorestframework

プロジェクトとアプリを準備します。

python manage.py startproject test_project
python manage.py startapp test-api

コーディング

test_projectフォルダ内にあるsettings.pyを編集します。
rest_frameworkとtest_api.apps.TestApiConfigを追加します。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'test_api.apps.TestApiConfig',
]

test_apiフォルダの中にurls.pyを作成します。
まずは、test_projectフォルダ内のurls.pyを次のように編集します。

from django.contrib import admin
from django.urls import path
from django.conf.urls import include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/',include('api.urls')),
]

モデルを準備します。
test_apiフォルダの中のmodels.pyを次のように入力します。
(ちょっと作りたいものがあって、その設定に合わせています。)

from django.db import models
from django.utils import timezone

ATTENDANCE_CHOICE = (
    (1,"出勤"),
    (2,"退勤"),
)

STR_ATTENDANCE_ARRAY = ["","出勤","退勤"]

class TestApiModel(models.Model):
    type = models.IntegerField(choices=ATTENDANCE_CHOICE)
    created_at = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return STR_ATTENDANCE_ARRAY[self.type] + ":" + str(self.created_at)

typeには出勤と退勤の選択肢を与えたいので、IntegerFieldにchoicesを設定しています。
created_atには作成した日時を保存します。
created_atはDateTimeFieldにdefault=timezone.nowを設定します。
次のコマンドを実行して、マイグレーションを実行します。

python manage.py makemigrations
python manage.py migrate

adminからモデルの追加などができますが、上で作ったTestApiModelをadminから触ることができるように次のようにadmin.pyを変更します。

from django.contrib import admin
from .models import TestApiModel

admin.site.register(TestApiModel)

一回動作確認をします。
そのためにまずは、superuserを作成します。

python manage.py createsuperuser

ユーザー名とパスワードを入力すると作成が完了します。

内部のサーバーを立ち上げます。

python manage.py runserver

PyCharmを使用しているのであれば、manage.pyを右クリックして実行を行います。
右上にmanage.pyと表示されるので、そこをクリックして「構成の編集」を選択します。

構成のパラメータに「runserver」と記入します。

その後に、右上の三角形を押すとrunserverが実行されます。
http://127.0.0.1:8000/admin/

adminページに上で設定したユーザー名とパスワードでログインできます。
TestApiModelを選択して、ADD TEST API MODELをクリックするとデータを追加することができます。

APIを作っていきます。
test_apiフォルダにserializers.pyを作成します。
serializers.pyに次のように記入します。
serializerは送信されてくるデータとモデルの間の変換やデータのバリデーションを行うなどの役割があります。

from rest_framework import serializers
from .models import TestApiModel

class TestApiSerializer(serializers.ModelSerializer):
    created_at = serializers.DateTimeField(format="%Y-%m-%d %H:%M", read_only=True)

    class Meta:
        model = TestApiModel
        fields = ['id', 'type', 'created_at']

serialzers.ModelSerializerを継承してクラスを作り、class Metaのmodelに対象のモデルを、fieldsに利用するモデルのフィールドを指定します。

次にtest_apiフォルダのviews.pyを記入します。

from rest_framework import viewsets
from .serializers import TestApiSerializer
from .models import TestApiModel

class TestApiViewSet(viewsets.ModelViewSet):
    queryset = TestApiModel.objects.all()
    serializer_class = TestApiSerializer

ModelViewSetを継承していますが、これは1つのモデルのGETやPOSTなどREST APIの機能をすばやく実装したい時に使えます。
このクラスを継承した場合、querysetとserializer_classを指定することが必須です。

最後にtest_apiフォルダのurls.pyを記述して、APIにアクセスするためのURLを与えます。

from django.conf.urls import include
from django.urls import path
from .views import TestApiViewSet
from rest_framework import routers

router = routers.DefaultRouter()
router.register('test',TestApiViewSet)

urlpatterns = [
    path('',include(router.urls)),
]

動作確認

curlで動作確認をしてみます。
ターミナルを開きます。
まずはGETしてみます。

curl --request GET --url http://127.0.0.1:8000/test_api/test/

作成したデータがjson形式で取得できたと思います。

次にPOSTを試してみます。

curl --request POST --url http://127.0.0.1:8000/test_api/test/ --header 'content-type: application/x-www-form-urlencoded' --data type=1

GETしてみるとデータが増えていると思います。

次に上で作成したデータを消去したいと思います。
GETして得られたidをtest/の後に入力してください。(僕の場合は5です)

curl --request DELETE --url http://127.0.0.1:8000/test_api/test/5/

もう一度GETしてみると作成したデータが削除されていると思います。

最後に

Django Rest Frameworkを使ってみました。
Serializer以外はDjangoを使うのとあんまり変わらないので、実装は簡単でした。

次は今回作ったAPIをvisual studio codeのREST ClientからAPIを叩いてみたいと思います。

最後までご覧いただき、ありがとうございます。
以上、「Django Rest Frameworkを使ってみよう!」でした。

ABOUT ME
MSK
九州在住の組み込み系エンジニアです。 2児の父親でもあります。 数学やプログラミングが趣味です。 最近RustとReact、結び目理論と曲面結び目理論にはまっています。