Django で REST API を作る場合、大まかな流れとしては Python 仮想環境内に作った Django プロジェクトに API 用の独自のアプリケーションを作り、その中にシリアライザ(データを JSON 形式に変換する機能)と View を作ります。
ここで紹介するのは単純にテーブル内のデータを全て GET で抽出してそのまま JSON 形式で返すだけのものです。POST や DELETE などは触れていません。
- 下準備
- API 用 Django アプリケーションの作成
- djangorestframework のインストール
- urls.py の設定
- models.py にモデルを記述
- シリアライザの作成
- ビューの作成
- class based view の場合
- function based view の場合
- 動作確認
下準備
API 用 Django アプリケーションの作成
API 用にアプリケーション「api」を作成します。
% python manage.py startapp api
settings.py の INSTALLED_APPS に追加します。
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'api.apps.ApiConfig', # 追記 ]
djangorestframework のインストール
コマンド「pip install djangorestframework」を実行します。
% pip install djangorestframework Collecting djangorestframework Downloading djangorestframework-3.12.4-py3-none-any.whl (957 kB) |████████████████████████████████| 957 kB 4.1 MB/s Requirement already satisfied: django>=2.2 in /Users/ユーザー名/PythonProjects/仮想環境名/lib/python3.8/site-packages (from djangorestframework) (3.2) Requirement already satisfied: pytz in /Users/ユーザー名/PythonProjects/仮想環境名/lib/python3.8/site-packages (from django>=2.2->djangorestframework) (2021.1) Requirement already satisfied: sqlparse>=0.2.2 in /Users/ユーザー名/PythonProjects/仮想環境名/lib/python3.8/site-packages (from django>=2.2->djangorestframework) (0.4.1) Requirement already satisfied: asgiref<4,>=3.3.2 in /Users/ユーザー名/PythonProjects/仮想環境名/lib/python3.8/site-packages (from django>=2.2->djangorestframework) (3.3.4) Installing collected packages: djangorestframework Successfully installed djangorestframework-3.12.4 %
settings.py の INSTALLED_APPS に追加します。
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'api.apps.ApiConfig', 'rest_framework', # 追記 ]
urls.py の設定
アプリケーション「api」ディレクトリに url.py を作成した上で、プロジェクトレベルの url.py から参照します。
from django.contrib import admin from django.urls import path, include # 追記 urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('api.urls')), # 追記 ]
models.py にモデルを記述
API で使用したいモデルを models.py に記述します。
今回すでにデータベース上にテーブルを用意してあるのでコマンド「python manage.py inspectdb テーブル名」でモデル情報を抽出します。
% python manage.py inspectdb yt_analysis_07 # This is an auto-generated Django model module. # You'll have to do the following manually to clean this up: # * Rearrange models' order # * Make sure each model has one field with primary_key=True # * Make sure each ForeignKey and OneToOneField has `on_delete` set to the desired behavior # * Remove `managed = False` lines if you wish to allow Django to create, modify, and delete the table # Feel free to rename the models, but don't rename db_table values or field names. from django.db import models class YtAnalysis07(models.Model): channel_id = models.CharField(max_length=40, blank=True, null=True) channel_name = models.TextField(blank=True, null=True) view_count = models.BigIntegerField(blank=True, null=True) like_count = models.IntegerField(blank=True, null=True) dislike_count = models.IntegerField(blank=True, null=True) favorite_count = models.IntegerField(blank=True, null=True) comment_count = models.IntegerField(blank=True, null=True) video_count = models.IntegerField(blank=True, null=True) class Meta: managed = False db_table = 'yt_analysis_07' %
クラス文を models.py にコピーしますが、その際に 1 つ「primary_key=True」のフィールドを持つ必要があるそうです。
シリアライザの作成
Python のリスト・辞書形式のデータを JSON に変換するためのシリアライザを作成します。
アプリケーションフォルダ(今回は api/ )に「serializers.py」というファイルを作成します。
from rest_framework import serializers from .models import YtAnalysis07 # モデルをインポート class APISerializer(serializers.ModelSerializer): class Meta: model = YtAnalysis07 # 使用するモデル fields = '__all__' # 処理対象にするフィールド(今回は全項目)
ビューの作成
API のビューを作成します。ざっくり言うとモデルからデータを抽出し、シリアライザに渡して JSON に変換し、その JSON データをレスポンスとして返します。
class based view の場合
from rest_framework import viewsets from .serializers import APISerializer from .models import YtAnalysis07 class DataListView(viewsets.ModelViewSet): queryset = YtAnalysis07.objects.all() # モデルからデータを抽出するクエリセット serializer_class = APISerializer # 使用するシリアライザ
urls.py の設定は下記の様にします。
from django.urls import path from . import views app_name = 'api' urlpatterns = [ path('data-list/', views.DataListView.as_view({'get': 'list'}), name="data-list"), ]
function based view の場合
from rest_framework.decorators import api_view from rest_framework.response import Response from .serializers import APISerializer from .models import YtAnalysis07 @api_view(['GET']) # GET のみに対応 def dataList(request): api_data = YtAnalysis07.objects.all() # モデルからデータを抽出する serializer = APISerializer(api_data, many=True) # シリアライザにデータを渡す return Response(serializer.data) シリアル可されたデータを return で返す
urls.py の設定は下記の様にします。
from django.urls import path from . import views app_name = 'api' urlpatterns = [ path('data-list/', views.dataList, name="data-list"), ]
動作確認
設定した URL をブラウザに打ち込むと下記の様な画面が表示されます。JSON データも見えます。

ブラウザで URL を叩くと上記の様な画面で表示されますが、例えばターミナルで URL を requests.get すると下記の様に JSON 形式のデータだけが返ってきます。
>>> import requests >>> r = requests.get('http://127.0.0.1:8000/api/data-list/') >>> r.text '[{"channel_id":"UCLkAepWjdylmXSltofFvsYQ","channel_name":"BANGTANTV","view_count":22423409,"like_count":7325674,"dislike_count":20936,"favorite_count":0,"comment_count":381315,"video_count":9},{"channel_id":"UCE_M8A5yxnLfW0KghEeajjw","channel_name":"Apple","view_count":19044060,"like_count":600159,"dislike_count":21023,"favorite_count":0,"comment_count":0,"video_count":10},
これを Django のテンプレートから JavaScript で呼び出すなどして活用します。