Django REST Framework で API 作成


はじめに

フロントエンド [React.js] & バックエンド [Django REST Framework] という組み合わせでウェブアプリ開発をしてみる。この記事では、DRF でウェブ API を作成しフロントエンド側からデータを取得できるようにする。動作環境は以下。

  • OS: Windows 10 Pro (WSL2 Ubuntu-20.04)
  • Python: 3.8.5
  • Django: 3.2
  • djangorestframework: 3.12.4

インストールおよびセットアップ

DRF をインストールし、使用できる状況にするためのセットアップについて説明する。Django 自体のインストールやプロジェクトの作成などといった基本的な説明は割愛する。
まず以下コマンドで DRF をインストールする。

$ pip install djangorestframework

続いて、API を作成したいプロジェクトの settings.py にて 'rest_framework' を追記する。

config/settings.py
# Application definition

INSTALLED_APPS = [
    ...
    'rest_framework',
]

これで DRF を読み込んで、使用することができる。

ウェブ API 作成の流れ

DRF を用いたウェブ API を作成するには、Model, Serializer, ViewSet, URL パターン の4項目を定義する必要がある。api というアプリを作成し、それぞれ準備していく。

Model

Model は、データベースのレコードをモデルクラスのオブジェクトとして扱うことができる。一からモデルクラスを定義することもできるが、ここでは既存のデータベースからモデルを自動で定義する。既存のデータベースを利用する方法は、Djangoで既存のPostgreSQLを利用を参照。
たとえば、ID と時刻、緯度経度をもつようなデータベースを使うと、以下のようなモデルが定義されるので、これを用いていく。

api/models.py
from django.db import models

class Info(models.Model):
    id = models.CharField(primary_key=True, max_length=12)
    utcdate = models.DateTimeField()
    latitude = models.DecimalField(max_digits=8, decimal_places=6)
    longitude = models.DecimalField(max_digits=9, decimal_places=6)

    class Meta:
        managed = False
        db_table = 'info'
        unique_together = (('id', 'utcdate'),)

Serializer

Serializer は、クエリセットやモデルインスタンスなどの複雑なデータを変換することができる。上記で定義した Model を読み込んで Serializer を定義すると、以下のようになる。

api/serializers.py
from rest_framework import serializers
from .models import Info

class InfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Info
        fields = '__all__'

ViewSet

Viewset は、これまでに定義した Model のオブジェクトや Serializer を指定して、どのように扱うかを決める。Viewset は以下のようになる。

api/views.py
from .models import Info
from .serializers import InfoSerializer
from rest_framework import viewsets

class InfoViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Info.objects.all()
    serializer_class = InfoSerializer

ReadOnly の ViewSet を継承して、クエリセットに Info オブジェクトの全データ、シリアライザークラスに InfoSerializer を指定している。

URL パターン

URL パターンは、リクエストがどの ViewSet に対応するかを振り分ける。DRF には router という機能があり、ここに URL パターンを登録する。router を使わない通常の設定でも可能。

api/ursl.py
from django.urls import path, re_path, include
from rest_framework.routers import DefaultRouter
from . import views

app_name = 'api'
router = DefaultRouter()
router.register(r'info', views.InfoViewSet)

# The API URLs are now determined automatically by the router.
urlpatterns = [
    path('', include(router.urls)),
]

プロジェクトの urls.py にて、上記で設定した URL パターンを読み込む。

config/ursl.py
from django.contrib import admin
from django.urls import include, path

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

API 動作確認

ここまでで API が作成できているはずなので、開発用サーバーにて動作確認をする。python manage.py runserver で開発用サーバーを立ち上げ、http://localhost:8000/api/ にアクセスすると API コンソールが立ち上がることが確認できる。さらに http://localhost:8000/api/info へアクセスすると、定義したデータを取得できるエンドポイントができていることが確認できる。

おわりに

DRF でウェブ API を作成した。React.js で作成したフロントエンドから今回作成した API のデータを取得したり、リクエストに応じてデータをフィルタリングするということを追加で実践していく。