Django! Django! Django!

この投稿は PyLadies Advent Calendar 2018 の9日目の記事です。

このタイトルにピンと来た方、さては村上春樹ファンですね。(一応元ネタ

ではなく、今年はまさにDjangoの年でしたね(個人的見解)。

PyLadiesもくもく会や合宿でも「今日はDjangoの勉強します!!」という方がとても多かったです。

その中でも、Django Rest Fremewark(以下DRF)を学びたい方が多く、どうやって勉強すればいいか聞かれる機会が増えましたので、超ざっくりDRFの全体像と自分が勉強した方法を紹介したいと思います。

※ ここで紹介する例は、Django REST framework Quickstartで作成したプロジェクトを元にしています。5分程度で、さくっとDRFのプロジェクトが作成できますので、ぜひお試しください。

Django REST framework(DRF)

RestfulなAPIということは、モデルと1対1で結びつくようにAPIを作っていくイメージだと思います。 1モデル内のリソースに対して一覧を問い合わせたり、モデルの各レコードに対して追加・更新・削除を行いますので、それをDRFで実現するためには、最小限下記の設定が必要です。

f:id:electricSheep:20181209132626p:plain

(1) URLConf

プロジェクト作成時に自動生成される urls.pyは 、あるURLに対してリクエストが送られた場合、レスポンスを返すビュー関数を指定するための設定を行うためのものです。

Quickstartの例では、URLConf(urls.py)にRouterを使用して設定しています。

router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)

## Router

  • RouterにはSimpleRouterとDefaultRouterの2つが用意されています。
  • ネストしたエンドポイントを対応可能にするpackagesもあります
  • Routerに登録できるのはViewSetのみで、APIView / GenericAPIViewでは利用できませんが、ViewSetをルータクラスに登録するだけで、APIのURLconfを自動的に生成できます。
  • ViewSet以外では、urlpatterns にURLのパターンとそれに紐付けるビュー関数を追加します。

(2)View

  • 役割としては、Webリクエストを引数にとり、 Webレスポンスを返します。
  • Viewは下記種類があります。

    • ViewSets
    • Views
      • Function view:関数ベースのビューを扱うための@api_viewデコレータを使用して定義する
      • Class based view:クラスベースのビューを扱うためのAPIViewクラスを継承して定義する
    • Genericviews
  • リクエストパースをサポートするRequestオブジェクトが提供されていて、下記により、POST, PUT, PATCH メソッド のリクエストの場合にリクエストボディを解析したものが辞書形式で取得することができます。

request.data

※なんと、この1行でファイルおよび非ファイル入力を含む、すべての解析されたコンテンツを取得することができる。parser_classesを指定すれば、勝手に解析してエラーを返してくれたりもする。

  • DRFはResponseオブジェクトも提供します。
  • ResponseはWebページ(HTML)やエラー、jsonドキュメントやPNGJPEGといった画像など、何でも返す事ができます。

(3) Serializer

  • HTTPResponseで返すために、modelのインスタンスjson などの出力可能な形式に変換するための手段を提供します。
  • また、Requestで受け取ったストリームをPythonで扱えるデータ型にパースして、オブジェクトインスタンスに復元します。(デシリアライズ
  • serializersは4つ用意されています。
    • serializers.Serializer
    • serializers.ModelSerializer
    • serializers.ListSerializer
    • serializers.HyperlinkedModelSerializer
  • ネストしたモデルの作成・更新に便利なthird-party packagesもあります  - https://github.com/beda-software/drf-writable-nested
  • バリデーションはSerializerで、決まったルールによって実行されます。コード上は簡潔にかけるのですが、内部で行われいてる実行順序などを把握していないと、???になりますので、最後に記載した参考ページを参考にするとよいと思います。ここでは詳細を省きます。

勉強法

ここまで見てわかったように、Router、View、Serliarizerごとに、いろいろな種類が存在するので最初混乱しがちです。(少なくとも自分は混乱した。。) これに加え、DRFでは例えば以下のような便利機能がたくさん提供されていて、そういった機能を把握するも大切です。

  • (例)特定のビューにアクセスできるユーザを制限するのに便利なパーミッションクラス
from rest_framework import permissions
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

viewにたったこの2行を記述するだけで、認証されたユーザーに対しては完全にアクセスできるようにし、認証されていないユーザーには読み取り専用アクセスを許可するという設定をすることができます。 最初、あまりにも少ない記述でいろいろ実現できていて、いったいそれらの処理はどこに書かれているんだ!とこれまた混乱しました。

ここではざっくりと概要だけ書きましたが、詳細に関しては、下記参考になるページ、本を列挙しましたので、そちらを参照してもらうとすっきりわかると思います。

それぞれたくさん種類がありますが、用法によって使い分けができると思いますので、まずはそれぞれで何ができるのか・できないのか、どんな機能が提供されているのかを把握するのが近道かと思います!

また、自分がやりたいことを実現できそうなものを見つけたら、先に説明したQuickstartのようなシンプルなプロジェクトを作成して、django-rest-framework の内容をもとに1つずつ動きを確かめる方法が自分はわかりやすかったです。

Let's enjoy DRF !

参考ページ