Django REST Frameworkを使ってモデルの内容をJSONで返すWeb APIを作成する

この記事ではDjango REST Frameworkを使ってモデルの内容をJSONにして返すWeb APIを作成します。

Django REST Frameworkはサードパーティーアプリとしてインストールできます。
具体的な作業内容は以下のとおりです。

  1. djangorestframeworkをインストールする
  2. settings.pyのINSTALLED_APPSにrest_frameworkを読み込む
  3. startappコマンドでAPI用アプリケーションを作成する
  4. URLパターンを定義する
  5. ビューを作成する
  6. ビューで使用するシリアライザクラスを作成する
  7. JSONを取得してみる

本記事で作業の内容を順番に紹介していきます。

またDjango REST Frameworkを使う前提として、あらかじめDjangoプロジェクトが作成されていて、そこでModelなどが定義されている必要があります。

これらの事前準備の内容も記事の最後に記録しておきます。
ゼロからWeb APIを作ってみたい方は参考にしてください。

Django REST Frameworkを利用する

以下のコマンドでdjangorestframeworkをインストールします。

% pipenv install djangorestframework==3.11.0

次にプロジェクトレベルのsettings.pyを編集して、rest_frameworkを読み込みます。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # 3rd party
    'rest_framework',

    # ローカルアプリケーション
    'books.apps.BooksConfig',

]

REST APIを提供するために、「api」というアプリケーションを作成します。

% python manage.py startapp api

アプリケーションを作成した後は、プロジェクトレベルのsettings.pyを編集し、INSTALLED_APPSに追加します。

# apiexample_project/settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # 3rd party
    'rest_framework',

    # ローカルアプリケーション
    'books.apps.BooksConfig',
    'api.apps.ApiConfig', # 追加

]

次にURLの設定です。

/api/にアクセスすればデータを取得できるようにURLを設定します。
プロジェクトレベルのurls.pyを編集しましょう。

# apiexample_project/urls.py
from django.contrib import admin
from django.urls import path, include

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

作成したapiアプリケーションにurls.pyを追加します。
ディレクトリ構成は以下のようになっています。

├── api
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
# api/urls.py

from django.urls import path

from .views import BookAPIView

urlpatterns = [
  path('', BookAPIView.as_view()),
]

ビューを作成する

モデルのデータをシリアライズするためのビューを作成しましょう。

api/views.pyを編集します。

# api/views.py
from rest_framework import generics

from books.models import Book
from .serializers import BookSerializer

# Create your views here.
class BookAPIView(generics.ListAPIView):
  queryset = Book.objects.all()
  serializer_class = BookSerializer

Serializerを作成する

上のビューで読み込んでいるserializers.pyを作っていきます。

データをJSONに変換するためのシリアライザです。
api/serializers.pyを作成し、以下のようにコードを書いてください。

# api/serializers.py

from rest_framework import serializers

from books.models import Book

class BookSerializer(serializers.ModelSerializer):
  class Meta:
    model = Book
    fields = ('title', 'subtitle', 'author', 'isbn')

APIを確認する

ブラウザでhttp://127.0.0.1:8000/api/を表示しましょう。
JSONが取得できます。

cURLでも取得可能です。

 % curl http://127.0.0.1:8000/api/ | jq  
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   258  100   258    0     0  28666      0 --:--:-- --:--:-- --:--:-- 28666
[
  {
    "title": "阿部寛の秘密",
    "subtitle": "阿部寛はローマ人だった",
    "author": "阿部寛の弟",
    "isbn": "hirosiabe"
  },
  {
    "title": "橋本環奈の秘密",
    "subtitle": "実は西麻布で飲み歩いてる",
    "author": "橋本環奈の母親",
    "isbn": "kannna"
  }

事前準備

任意のディレクトリを作り、以下のコマンドを順番に実行していきます。
pipenvはインストールされているものとします。

% pipenv install django==3.0.3
% pipenv shell
% django-admin startproject apiexample_project .
% python manage.py migrate

アプリケーションを作る

以下のコマンドでアプリケーションを作ります。

「本の名前や著者」を表示するアプリケーションのイメージです。

% python manage.py startapp books 

プロジェクトのsetgins.pyのINSTALLED_APPを編集します。

# apiexample_project/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # Local Application
    'books.apps.BooksConfig', # new
]

マイグレーションを実行します。

% python manage.py migrate

モデルを作成します。

# books/models.py
from django.db import models

# Create your models here.
class Book(models.Model):
  title = models.CharField(max_length=250)
  subtitle = models.CharField(max_length=250)
  author = models.CharField(max_length=100)
  isbn = models.CharField(max_length=13)

  def __str__(self):
    return self.title + ':' + self.author

モデルを作成したので、再度マイグレーションを実行します。

% python manage.py makemigrations books
% python manage.py migrate

ここまででモデルを作成できたので、管理者ユーザーを作ってモデルにデータを追加してみます。

% python manage.py createsuperuser

admin.pyにモデルを登録します。

# books/admin.py
from django.contrib import admin
from .models import Book

admin.site.register(Book)

http://127.0.0.1:8000/admin/login/?next=/admin/にアクセスしてログインします。

すると、管理者画面が現れるので、データベースにデータを登録します。

ビューを作成します。

# books/views.py
from django.views.generic import ListView

from .models import Book

# Create your views here.
class BookListView(ListView):
  model = Book
  template_name = 'book_list.html'

次にURLを設定します。
まずはプロジェクトのurls.pyを編集し、アプリケーション上のurls.pyを読み込むようにします。

# apiexample_project/urls.py

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('books.urls')), # 追加
]

books/urls.pyを作成します。

# books/urls.py

from django.urls import path
from .views import BookListView

urlpatterns = [
  path('', BookListView.as_view(), name='home')
]

最後にテンプレートを作成します。
books/templates/booksディレクトリを作り、その下にbook_list.htmlを作ります。

ディレクトリのイメージは以下のとおりです。

├── books
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   ├── 0001_initial.py
│   │   └── __init__.py
│   ├── models.py
│   ├── templates
│   │   └── books
│   │       └── book_list.html

book_list.htmlは以下のように書きます。

<h1>本の一覧</h1>
{% for book in object_list %}
  <ul>
    <li>タイトル:{{ book.title }}</li>
    <li>サブタイトル:{{ book.subtitle }}</li>
    <li>著者:{{ book.author }}</li>
    <li>ISBN:{{ book.isbn }}</li>
  </ul>
{% endfor %}

http://127.0.0.1:8000/にアクセスすると以下のような一覧画面が表示されます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です