SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

モダンDjango入門

Django 2.0リリース! 最新のDjangoで作るカンバンボードアプリ ~ モデルの定義とDjango REST frameworkの実装

モダンDjango入門 第2回

Django REST framework(1)

 モデルの定義の次は、RESTful APIの実装に取り掛かりましょう。Djangoコミュニティには、Web API構築の際に便利なパッケージが数多くありますが、今回はデファクトスタンダードとなっているDjango REST frameworkを使用していきます。

 Django REST frameworkのほかにどのようなパッケージがあるのかは、Django PackageというサイトのAPI Creationのページから調べられます。このDjango Packageは開発頻度や特徴などが一覧・比較でき、Django関連のパッケージを調べる際には重宝します。

 Django REST frameworkをインストールして、settingsを更新しておきましょう。

(env) $ pip install djangorestframework
Collecting djangorestframework
  Downloading djangorestframework-3.7.7-py2.py3-none-any.whl (1.1MB)
    100% |████████████████████████████████| 1.1MB 10.3MB/s
Installing collected packages: djangorestframework
Successfully installed djangorestframework-3.7.7
(env) $ vi requirements/base.txt
(env) $ cat requirements/base.txt
Django==2.0.2
django-model-utils==3.1.1
djangorestframework==3.7.7
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework', # rest_frameworkを追加
    'kanban.board.apps.BoardConfig',
]

 設定はこれだけで完了です。Django REST frameworkの機能を使って、Ticketモデルを操作するRESTful APIの実装を進めていきます。

シリアライザーの作成

 シリアライズとは、オブジェクトをバイト列など出力可能なデータに書き出すことです。日本語では直列化とも呼ばれます。デシリアライズとは、逆にソフトウェアで扱うために元の形式に復元する処理のことを指します。Djano REST frameworkのModelSerializerを利用すると、Djangのモデルオブジェクトのシリアライズ・デシリアライズが簡単に実装できます。

 APIのレスポンスとして、先ほど作成したTicketオブジェクトを、次のようなJSONとして出力することを目指していきます。

{
    "id": 1,
    "name": "ticket 1",
    "description": "This is the first ticket.",
    "status": 1,
    "status_display": "ToDo",
    "assignee": "massa142",
    "start": null,
    "end": null
}

 kanban/board/serializer.pyファイルを作成して、TicketSerializerを以下のように実装します。

from django.contrib.auth import get_user_model
from rest_framework import serializers

from .models import Ticket

User = get_user_model()


class TicketSerializer(serializers.ModelSerializer):
    assignee = serializers.SlugRelatedField(
        slug_field=User.USERNAME_FIELD, queryset=User.objects.all(), allow_null=True)
    status_display = serializers.SerializerMethodField()

    class Meta:
        model = Ticket
        exclude = ('created', 'modified')

    def get_status_display(self, obj):
        return obj.get_status_display()

 Metaオプションのそれぞれの役割は以下の通りです。

オプション名 役割
model serializerが扱うモデルを指定
exclude serializerが扱わないフィールドを指定(扱うフィールドを指定する場合はfieldsオプションを使用)

 statusはデータとしては単なる数値でしかないので、そのまま出力しても何をする値かわからず扱いづらいです。そのため人間にもわかりやすい文字列データを、読み込み専用のstatus_displayフィールドとして定義します。

 このstatus_displayフィールドは、serializers.SerializerMethodFieldとして実装しています。SerializerMethodFieldはデフォルトでread_onlyになっており、get_<field_name>メソッドを通じて値を返します。そのメソッドを実装しているのが、以下のコードです。

    def get_status_display(self, obj):
        return obj.get_status_display()

 このobj.get_status_display()とは、statusフィールドのchoicesオプションで指定した表示用の文字列を取得できるメソッドです。言葉で説明するよりもコードを見たほうが理解しやすいと思うので、以下のコードを確認してください。

(env) $ python manage.py shell_plus
>>> ticket = Ticket.objects.get(id=1)
>>> ticket.status
1
>>> ticket.get_status_display()
'ToDo'

 これはDjangoの備え付けの機能で、choicesオプションを持つすべてのフィールドでget_<field_name>_display()メソッドが使えます。

 またassigneeには、SlugRelatedFieldを適用しています。SlugRelatedFieldは、ForeignKeyなどリレーション関連のフィールドに対して使用します。slug_fieldオプションでは、出力する際に使用するリレーション先のフィールドを指定しています。またquerysetで指定した値は、入力値のバリデーションに使われます。allow_nullは、このフィールドにNULLとなる値を許可するかどうかを決めています。

 以上でSerializerの実装がひとまず完成しました。次はこのSerializerを使ったview.pyの実装に移りましょう。

ビューの作成

 Django REST frameworkが用意しているModelViewSetを利用すると、HTTPメソッドに対応してDjangoモデルのCRUD操作を行うview関数の実装が簡単にできます。

 kanban/borad/view.pyファイルを以下のように実装します。

from rest_framework import viewsets

from .models import Ticket
from .serializers import TicketSerializer


class TicketViewSet(viewsets.ModelViewSet):
    queryset = Ticket.objects.all()
    serializer_class = TicketSerializer

 一覧表示に実行されるquerysetと、シリアライズ・デシリアライズで使用するserializer_classを指定するだけでOKです。このようにModelViewSetはモデルに密接に紐づいていて、開発者にとっては抽象度が高いものとなっています。

 ここで実装したビューをURLのルーティングに紐づけて実際にアクセスできるようにするために、ルーターの設定を次に行いましょう。

ルーターの設定

 Django REST frameworkは、上記で実装したようなViewSetを扱うために便利なURLルーティング機能を提供しています。config/urls.pyを次のように編集しましょう。

from django.urls import include, path
from django.contrib import admin
from rest_framework.routers import DefaultRouter

from kanban.board.views import TicketViewSet

router = DefaultRouter()
router.register('tickets', TicketViewSet)

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

 router.registerの第一引数にはURLプリフィックスを、第二引数にはViewSetを指定して、ルーティングに登録していきます。そしてurlpatternsに、url('^api/', include(router.urls))を追加しています。これで/api/配下にrouterに登録したルーティングルールを反映できます。

次のページ
Django REST framework(2)

この記事は参考になりましたか?

モダンDjango入門連載記事一覧

もっと読む

この記事の著者

新井 正貴(アライ マサタカ)

 東京大学文学部卒業、アライドアーキテクツ株式会社にて勤務。2016年4月、株式会社SQUEEZEに入社。コミュニティ活動として、PyCon JP 2015〜 スタッフ、Pythonもくもく会の主催を行う。趣味はラクロスとPerfume。 Site:http://massa142.github.io/ Twitter:@massa142 Facebook:新井 正貴

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/10722 2018/03/15 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー