Python | Web フレームワーク:Django REST Framework

Python
スポンサーリンク

概要(Django REST Framework=「Django で API を作るためのフル装備セット」)

Django REST Framework(DRF)は、

「Django を使って、ブラウザではなく“プログラム同士が話すための API”を作るためのフレームワーク」

です。

普通の Django は「HTML を返す Web サイト」を作るのが得意ですが、
DRF を使うと、

JSON を返す API
スマホアプリやフロントエンド(React/Vue など)から叩かれるバックエンド
外部サービス向けの Web API

を、かなり少ないコードで、しかもきちんとした形で作れるようになります。

ここから、

REST API のざっくりしたイメージ
DRF を使うと何が楽になるのか
シリアライザ・ビュー・ルーターという三本柱
実際のコード例(超シンプルな CRUD)
初心者がまず押さえるべき設計のポイント

を、順番にかみ砕いていきます。

REST API と Django REST Framework の関係をイメージする

REST API ってそもそも何をしているのか

REST API は、ざっくり言うと、

「URL と HTTP メソッド(GET, POST, PUT, DELETE など)を使って、
データを取り出したり、作ったり、更新したり、消したりするための“約束事”」

です。

例えば、本(Book)を扱う API なら、こんな感じになります。

GET /api/books/ で本の一覧を JSON で返す
POST /api/books/ で新しい本を登録する
GET /api/books/1/ で id=1 の本の詳細を返す
PUT /api/books/1/ で id=1 の本を更新する
DELETE /api/books/1/ で id=1 の本を削除する

ブラウザで見る HTML ではなく、
プログラムが読みやすい JSON を返すのがポイントです。

Django REST Framework は、この「REST っぽい API」を
Django の上にきれいに乗せるための道具一式です。

なぜ「普通の Django だけ」だとつらくなるのか

もちろん、DRF を使わなくても、
普通の Django で JSON を返すビューを書くことはできます。

しかし、API をちゃんと作ろうとすると、

入力値のバリデーション
モデルと JSON の変換(シリアライズ)
認証・認可(ログインしているユーザーだけ許可など)
ページネーション(一覧をページ分割)
エラーレスポンスの統一

など、やることが一気に増えます。

これを全部手書きすると、
ビューが肥大化し、コピペだらけになり、
バグも増えます。

DRF は、これらを「部品」として用意してくれていて、

シリアライザ
APIView / ViewSet
ルーター
認証・パーミッション
ページネーション

などを組み合わせることで、
「ちゃんとした API」を少ないコードで作れるようにしてくれます。

DRF の三本柱(シリアライザ・ビュー・ルーター)

シリアライザ(Serializer)=「モデルと JSON の翻訳者」

シリアライザは、

「Python のオブジェクト(モデルインスタンスなど)と JSON の間を変換する役」

です。

モデルがこうだとします。

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=200)
    price = models.IntegerField()
Python

この Book を JSON にしたり、
JSON から Book を作ったりするために、
シリアライザを定義します。

from rest_framework import serializers
from .models import Book

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ["id", "title", "price"]
Python

これで、

Book インスタンス → {"id": 1, "title": "...", "price": 1000}
JSON データ → バリデーション → Book インスタンス

という変換を、DRF がやってくれるようになります。

ここが DRF の一番大事なポイントのひとつです。
「モデルと JSON の変換とバリデーションを、シリアライザに任せる」
という発想を持てるかどうかで、API の設計がかなり変わります。

ビュー(APIView / ViewSet)=「どの操作を許すかを決める場所」

DRF のビューは、
「どの HTTP メソッドで、どんな処理をするか」を決める場所です。

一番素直な書き方は APIView です。

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Book
from .serializers import BookSerializer

class BookListAPIView(APIView):
    def get(self, request):
        books = Book.objects.all()
        serializer = BookSerializer(books, many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = BookSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()  # Book を作成
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Python

ここでやっていることは、

GET のときは Book を全部取ってシリアライズして返す
POST のときは JSON をシリアライザに渡してバリデーションし、OK なら保存

という流れです。

普通の Django のビューと似ていますが、
Response が JSON になっていること、
シリアライザを通していることが大きな違いです。

さらに、DRF には ViewSet という「もっとまとめて書ける」仕組みもあります。

from rest_framework import viewsets

class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
Python

これだけで、

一覧(GET /books/)
作成(POST /books/)
詳細(GET /books/{id}/)
更新(PUT/PATCH /books/{id}/)
削除(DELETE /books/{id}/)

といった CRUD API が一気に揃います。

ルーター(Router)=「URL を自動でいい感じに生やす人」

ViewSet を使うときは、
ルーターを使うと URL パターンを自動生成できます。

from rest_framework.routers import DefaultRouter
from .views import BookViewSet

router = DefaultRouter()
router.register("books", BookViewSet, basename="book")
Python

プロジェクトの urls.py で、
この router.urls を include します。

from django.urls import path, include
from .router import router

urlpatterns = [
    path("api/", include(router.urls)),
]
Python

これで、

/api/books/
/api/books/1/

などの URL が自動で生えます。

URL を一つ一つ手で書かなくていいので、
API のエンドポイントが増えても管理しやすくなります。

実例:Book モデルのシンプルな CRUD API を作る流れ

1. モデルを用意する

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

class Book(models.Model):
    title = models.CharField(max_length=200)
    price = models.IntegerField()

    def __str__(self):
        return self.title
Python

2. シリアライザを作る

# app/serializers.py
from rest_framework import serializers
from .models import Book

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ["id", "title", "price"]
Python

3. ViewSet を作る

# app/views.py
from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer

class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
Python

4. ルーターで URL を生やす

# app/router.py
from rest_framework.routers import DefaultRouter
from .views import BookViewSet

router = DefaultRouter()
router.register("books", BookViewSet, basename="book")
Python
# project/urls.py
from django.urls import path, include
from app.router import router

urlpatterns = [
    path("api/", include(router.urls)),
]
Python

ここまで書いたら、
開発サーバーを起動して http://127.0.0.1:8000/api/books/ にアクセスしてみてください。

DRF の「ブラウザ用 API UI」が表示されて、
ブラウザからでも JSON API を試せます。

GET で一覧が見られ、
フォームから POST で新しい Book を作成でき、
各行をクリックすると詳細・更新・削除もできます。

この「ブラウザから触れる API UI」も、
DRF のかなり嬉しいポイントです。

認証・パーミッション・ページネーションのイメージ

認証とパーミッション(誰が何をできるか)

API では、「誰でも何でもできる」状態は危険です。

DRF には、
認証(Authentication)とパーミッション(Permissions)の仕組みが用意されています。

例えば、

認証済みユーザーだけ書き込みを許可する
読み取りは誰でも OK、書き込みは管理者だけ
特定の条件を満たすユーザーだけアクセス可能

といったルールを、クラスとして定義できます。

ビューや ViewSet に対して、

from rest_framework.permissions import IsAuthenticated

class BookViewSet(viewsets.ModelViewSet):
    permission_classes = [IsAuthenticated]
Python

のように書くと、
この API は「ログインしているユーザーだけ利用可能」になります。

より細かいルールを作りたい場合は、
カスタムパーミッションを定義することもできます。

ページネーション(一覧をページ分割する)

大量のデータを一度に返すと、
クライアントもサーバーもつらくなります。

DRF にはページネーション機能があり、
設定を少し書くだけで、

/api/books/?page=1
/api/books/?page=2

のようにページごとに分割して返せるようになります。

レスポンスには、

現在のページ
次のページの URL
前のページの URL
そのページの結果一覧

などが含まれます。

これも「ちゃんとした API」に必須の要素で、
DRF がいい感じに面倒を見てくれます。

初心者がまず押さえるべき DRF の設計のポイント

「シリアライザに責任を寄せる」感覚を持つ

普通の Django では、
フォームが「入力とバリデーションの責任者」でした。

DRF では、
シリアライザがその役割を担います。

どんなフィールドがあるか
どんな型か
必須かどうか
バリデーションルールは何か

を、シリアライザに書きます。

ビューは、

どのシリアライザを使うか決める
serializer.is_valid() を呼ぶ
serializer.save() でモデルを保存する

という「流れの制御」に集中させると、
コードがきれいになります。

「ViewSet+Router」で CRUD を一気に揃える

最初から APIView で全部手書きするより、
まずは ModelViewSet と Router を使って、

一覧
詳細
作成
更新
削除

を一気に揃えてしまう方が、
全体像を掴みやすいです。

そのあとで、

一部のメソッドだけカスタマイズしたり
独自のアクション(例: /books/{id}/publish/)を追加したり

という方向に進むと、
「DRF の世界観」が自然と身についていきます。

まとめ(Django REST Framework は「Django で API を作るための標準装備」)

Django REST Framework を初心者目線で整理すると、こうなります。

DRF は、Django で JSON を返す REST API を作るためのフレームワークで、シリアライザ・ビュー・ルーター・認証・ページネーションなど、API に必要な部品が一通り揃っている。
シリアライザは「モデルと JSON の翻訳者」であり、フィールド定義とバリデーションを一箇所にまとめることで、ビューの責務を軽くしてくれる。
APIView や ViewSet を使って「どの HTTP メソッドで何をするか」を書き、Router を使うと URL を自動で生やせるので、CRUD API を少ないコードで実装できる。
DRF のブラウザ用 API UI を使えば、ブラウザから直接 API を試せるので、初心者でも挙動を体で理解しやすい。

タイトルとURLをコピーしました