Python Django 入門トップページ


Django REST Framework による API 開発

  1. API とプロジェクトの概要
  2. Django REST Frameworkのインストール
  3. プロジェクトの作成
  4. 基本設定
  5. アプリケーションの作成と登録
  6. モデルの作成とマイグレーション
  7. テストデータの設定
  8. コメント一覧を出力する API
  9. コメント詳細情報を出力する API
  10. 新規投稿と更新・削除の API
  11. ページネーション
  12. 入力内容の検証(バリデーション)
  13. テストの自動化
  14. Shell でのユーザ登録
  15. Fixtures でのユーザ登録
  16. ユーザ認証を必須にする
  17. コメントにオーナ情報を追加
  18. 権限の設定:Case #1
  19. 権限の設定:Case #2
  20. Python から API への接続
  21. React アプリケーションからの API 接続と CORS エラーの回避

Django REST Framework による API 開発

コメント一覧を出力する API

前のページまでの手順は Web ページ版のコメント掲示板開発とほぼ同じでした.ここからはいよいよ API の作成に取り掛かります.

Web ページとして出力する際には,views.py から comment_list.html へデータを渡して一覧で表示していました.一方で API の場合には views.py から Serializer へデータを渡し, Serializer が JSON 形式などの適切な形式に変換してくれます.例えば,一覧表示や詳細表示の際に,Comment モデルから idtitlebodyupdated_at というフィールドだけを出力するようにします.

comments/serializers.pyfrom .models import Comment
from rest_framework import serializers

class CommentSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Comment
        fields = ['id', 'title', 'body', 'updated_at']

views.py には rest_framework のジェネリックビューを利用して,次のようなコードを書きます.

comments/views.pyfrom django.shortcuts import render
from rest_framework import generics
from .models import Comment
from .serializers import CommentSerializer

# Create your views here.

class CommentList(generics.ListAPIView):
    queryset = Comment.objects.all()
    serializer_class = CommentSerializer

comments フォルダ内に urls.py を作成し,comments/ というアドレスに対して views.py の CommentList クラスが呼び出されるようにします.

comments/urls.pyfrom django.urls import path
from comments import views

urlpatterns = [
    path('comments/', views.CommentList.as_view()),
]

さらにプロジェクト全体の urls.py から comments アプリケーションの urls.py をインクルードするようにします.

django_comment_api\urls.py(抜粋)from django.contrib import admin
from django.urls import path, include

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

ここで Web サーバを起動します.

...\django_comment_api>python manage.py runserver ⏎
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
November 23, 2023 - 14:57:18
Django version 4.2.7, using settings 'django_comment_api.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.

Web サーバの起動ができたら,別のコマンドプロンプトや Anaconda Prompt を起動して,curl (カール)コマンドを使って API を呼び出します.すると,API から JSON 形式でコメントの一覧が更新日時の降順で得られました.なお,curl コマンドは指定した URL に対して HTTP などのプロトコルでデータの送受信を行うことができるコマンドラインツールで,Windows 10/11 でも標準で利用できますcurl 公式サイトのチュートリアルには様々な使い方が掲載されています.下の実行結果で出力された JSON 形式のデータを見ると,Serializer で指定したフィールドだけが出力されており,created_at フィールドは含まれていないことにも注意してください.

...\django_comment_api>curl http://127.0.0.1:8000/comments/ ⏎
[{"id":9,"title":"9個目のコメント","body":"コメントの本文9","updated_at":"2023-11-23T11:20:00"},{"id":10,"title":"10個目のコメント","body":"コメントの本文10","updated_at":"2023-11-23T11:10:00"},{"id":8,"title":"8個目のコメント","body":"コメントの本文8","updated_at":"2023-11-23T11:08:00"},{"id":7,"title":"7個目のコメント","body":"コメントの本文7","updated_at":"2023-11-23T11:07:00"},{"id":6,"title":"6個目のコメント","body":"コメントの本文6","updated_at":"2023-11-23T11:06:00"},{"id":5,"title":"5個目のコメント","body":"コメントの本文5","updated_at":"2023-11-23T11:05:00"},{"id":4,"title":"4個目のコメント","body":"コメントの本文4","updated_at":"2023-11-23T11:04:00"},{"id":3,"title":"<3個目>のコメント","body":"<h1>コ メントの本文3</h1>","updated_at":"2023-11-23T11:03:00"},{"id":2,"title":"2個目のコメント","body":"コメントの本文2","updated_at":"2023-11-23T11:02:00"},{"id":1,"title":"最初のコメント","body":"コメントの本文","updated_at":"2023-11-23T11:01:00"}]
...\django_comment_api>

また,httpie をインストールした場合には http コマンドも利用できます.このとき,特にオプションのパラメータを指定しなければタブと改行で整形された JSON 形式で結果が出力されます.また,プロトコルと HTTP レスポンスステータスコード(200番は成功)などの情報も得られていることに注意してください.

...\django_comment_api>http http://127.0.0.1:8000/comments/ ⏎
HTTP/1.1 200 OK
Allow: GET, HEAD, OPTIONS
Content-Length: 1103
Content-Type: application/json
Cross-Origin-Opener-Policy: same-origin
Date: Thu, 23 Nov 2023 05:58:36 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.10.9
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

[
    {
        "body": "コメントの本文9",
        "id": 9,
        "title": "9個目のコメント",
        "updated_at": "2023-11-23T11:20:00"
    },
    {
        "body": "コメントの本文10",
        "id": 10,
        "title": "10個目のコメント",
        "updated_at": "2023-11-23T11:10:00"
    },
    {
        "body": "コメントの本文8",
        "id": 8,
        "title": "8個目のコメント",
        "updated_at": "2023-11-23T11:08:00"
    },
    {
        "body": "コメントの本文7",
        "id": 7,
        "title": "7個目のコメント",
        "updated_at": "2023-11-23T11:07:00"
    },
    {
        "body": "コメントの本文6",
        "id": 6,
        "title": "6個目のコメント",
        "updated_at": "2023-11-23T11:06:00"
    },
    {
        "body": "コメントの本文5",
        "id": 5,
        "title": "5個目のコメント",
        "updated_at": "2023-11-23T11:05:00"
    },
    {
        "body": "コメントの本文4",
        "id": 4,
        "title": "4個目のコメント",
        "updated_at": "2023-11-23T11:04:00"
    },
    {
        "body": "<h1>コメントの本文3</h1>",
        "id": 3,
        "title": "<3個目>のコメント",
        "updated_at": "2023-11-23T11:03:00"
    },
    {
        "body": "コメントの本文2",
        "id": 2,
        "title": "2個目のコメント",
        "updated_at": "2023-11-23T11:02:00"
    },
    {
        "body": "コメントの本文",
        "id": 1,
        "title": "最初のコメント",
        "updated_at": "2023-11-23T11:01:00"
    }
]



...\django_comment_api>

さらに,明示的に Accept:application/json というオプションを指定しても同じ結果が得られ,Accept:text/html を指定すると HTML 形式で出力されます.

...\django_comment_api>http http://127.0.0.1:8000/comments/ Accept:application/json ⏎
...\django_comment_api>http http://127.0.0.1:8000/comments/ Accept:text/html ⏎
...\django_comment_api>

もちろん Web ブラウザからも接続できるのですが,Django REST framework によって美しくデザインされたページとして表示されます.

django-api-2023-03

目次に戻る