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 開発

権限の設定:Case #2

前のページとこのページではここのコメントに対する権限について次の2つのケースを想定して設定します.

このページでは Case #2 を想定した設定を行います.Case #2 を実現するには views.py で次のようにすると良いでしょう.具体的にはまず,permission_classesIsAuthenticated を指定して,全ての操作で認証を必須にします.また,一覧表示と詳細表示(更新・削除も含む)での queryset をコメントアウト(または削除)して,get_queryset 関数を定義します.この関数では自身が投稿したコメントだけが取得できるように設定しています.

comments\views.py
from django.shortcuts import render
from rest_framework import generics
from rest_framework import permissions
from .models import Comment
from .serializers import CommentSerializer
from .paginations import LargeResultsSetPagination
# from .permissions import IsOwnerOrReadOnly # この行は不要

# Create your views here.

class CommentList(generics.ListCreateAPIView):
    # queryset = Comment.objects.all()
    serializer_class = CommentSerializer
    pagination_class = LargeResultsSetPagination
    permission_classes = [permissions.IsAuthenticated]

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)

    def get_queryset(self):
        queryset = Comment.objects.filter(owner_id=self.request.user.id)
        return queryset

class CommentDetail(generics.RetrieveUpdateDestroyAPIView):
    # queryset = Comment.objects.all()
    serializer_class = CommentSerializer
    permission_classes = [permissions.IsAuthenticated]

    def get_queryset(self):
        queryset = Comment.objects.filter(owner_id=self.request.user.id)
        return queryset

実際に動作を確認します.まず,認証情報を与えない場合は一切の操作ができません.

...\django_comment_api>curl http://127.0.0.1:8000/comments/ ⏎
{"detail":"認証情報が含まれていません。"}
...\django_comment_api>curl http://127.0.0.1:8000/comments/1/ ⏎
{"detail":"認証情報が含まれていません。"}
...\django_comment_api>curl -X POST -d "title=permission" -d "body=permissions" http://127.0.0.1:8000/comments/ ⏎
{"detail":"認証情報が含まれていません。"}
...\django_comment_api>curl -X PUT -d "title=put" -d "body=put body" http://127.0.0.1:8000/comments/1/ ⏎
{"detail":"認証情報が含まれていません。"}
...\django_comment_api>curl -X DELETE http://127.0.0.1:8000/comments/1/ ⏎
{"detail":"認証情報が含まれていません。"}

正しい認証情報を与えて一覧ページを3ページ表示したときには,どのページでも自分自身が投稿したコメントだけが表示されました.

...\django_comment_api>curl -u user_a:password http://127.0.0.1:8000/comments/ ⏎
{"count":7,"next":"http://127.0.0.1:8000/comments/?page=2","previous":null,"results":[{"id":1,"owner_id":1,"title":"edit","body":"body edit","updated_at":"2023-11-23T17:42:58.795269"},{"id":13,"owner_id":1,"title":"permission","body":"permissions","updated_at":"2023-11-23T17:41:38.364189"}]}
...\django_comment_api>curl -u user_a:password http://127.0.0.1:8000/comments/?page=2 ⏎
{"count":7,"next":"http://127.0.0.1:8000/comments/?page=3","previous":"http://127.0.0.1:8000/comments/","results":[{"id":11,"owner_id":1,"title":"owner","body":"store owner_id","updated_at":"2023-11-23T17:28:40.544771"},{"id":9,"owner_id":1,"title":"9個目のコメント","body":"コメントの本文9","updated_at":"2023-11-23T11:20:00"}]}
...\django_comment_api>curl -u user_a:password http://127.0.0.1:8000/comments/?page=3 ⏎
{"count":7,"next":"http://127.0.0.1:8000/comments/?page=4","previous":"http://127.0.0.1:8000/comments/?page=2","results":[{"id":7,"owner_id":1,"title":"7個目のコメント","body":"コメントの本文7","updated_at":"2023-11-23T11:07:00"},{"id":5,"owner_id":1,"title":"5個目のコメント","body":"コメントの本文5","updated_at":"2023-11-23T11:05:00"}]}

自身で投稿したコメントの詳細情報はもちろん閲覧可能です.

...\django_comment_api>curl -u user_a:password http://127.0.0.1:8000/comments/1/ ⏎
{"id":1,"owner_id":1,"title":"edit","body":"body edit","updated_at":"2023-11-23T17:42:58.795269"}

他のユーザの投稿コメントにアクセスする権限はありません.

...\django_comment_api>curl -u user_a:password http://127.0.0.1:8000/comments/2/ ⏎
{"detail":"見つかりませんでした。"}

認証情報を与えると新たなコメントを投稿することが可能です.

...\django_comment_api>curl -X POST -d "title=permission" -d "body=permissions" -u user_a:password http://127.0.0.1:8000/comments/ ⏎
{"id":14,"owner_id":1,"title":"permission","body":"permissions","updated_at":"2023-11-23T17:51:19.770160"}

自身で投稿したコメントは更新することが可能です.

...\django_comment_api>curl -X PUT -d "title=put" -d "body=put body" -u user_a:password http://127.0.0.1:8000/comments/1/ ⏎
{"id":1,"owner_id":1,"title":"put","body":"put body","updated_at":"2023-11-23T17:52:18.797868"}

他のユーザの投稿コメントにはアクセス権限がないので更新ももちろんできません.

...\django_comment_api>curl -X PUT -d "title=put" -d "body=put body" -u user_b:password http://127.0.0.1:8000/comments/1/ ⏎
{"detail":"見つかりませんでした。"}
...\django_comment_api>

Web ブラウザでも同じ動作になることを確認します.まず,ログインしていない状態では 403 エラーとなり,閲覧や投稿・編集が一切できません.

django-api-2023-18

ログインをすると一覧表示で自身のコメントだけが表示できます.

django-api-2023-24

2ページ目に移動してもやはり自身のコメントだけが表示されます.

django-api-2023-25

自分自身が投稿したコメントは表示ができて更新や削除も可能です.

django-api-2023-26

他のユーザのコメントは閲覧ができず,その結果として更新や削除ももちろんできません.

django-api-2023-27

目次に戻る