現時点では高々10件程度のコメントしか登録されていないので全てを出力しても構いませんが,件数が多くなるとページネーションの機能が必須になります.Django REST Framework には Pagination のためのクラスが定義されているのでこれを継承したクラスをつくります.これは comments フォルダに paginations.py を新規に作成すると良いでしょう.次の例では一覧で取得されるコメント件数を 2 件に制限しています.
comments\paginations.py
from rest_framework import pagination
class LargeResultsSetPagination(pagination.PageNumberPagination):
page_size = 2
page_size_query_param = 'page_size'
max_page_size = 5
そして views.py で今定義したクラスを指定するだけです.
comments\views.py
from django.shortcuts import render
from rest_framework import generics
from .models import Comment
from .serializers import CommentSerializer
from .paginations import LargeResultsSetPagination
# Create your views here.
class CommentList(generics.ListCreateAPIView):
queryset = Comment.objects.all()
serializer_class = CommentSerializer
pagination_class = LargeResultsSetPagination
class CommentDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Comment.objects.all()
serializer_class = CommentSerializer
実際に curl
コマンドでページネーションの動作を確認します.(1) ではパラメータを指定せずに一覧を取得しています.この結果,最新の2件が得られたのに加え,全体の件数,次のページの URL,前のページが存在しないこと,といった結果も得られています.(2) ではパラメータ ?page=2
を指定して2ページ目の内容を取得しています.(3) では存在しない100ページ目の内容を取得しようとした結果,「不正なページです」という出力が得られました.
...\django_comment_api>curl http://127.0.0.1:8000/comments/ ⏎ # (1) {"count":10,"next":"http://127.0.0.1:8000/comments/?page=2","previous":null,"results":[{"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"}]} ...\django_comment_api>curl http://127.0.0.1:8000/comments/?page=2 ⏎ # (2) {"count":10,"next":"http://127.0.0.1:8000/comments/?page=3","previous":"http://127.0.0.1:8000/comments/","results":[{"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"}]} ...\django_comment_api>curl http://127.0.0.1:8000/comments/?page=100 ⏎ # (3) {"detail":"不正なページです。"} ...\django_comment_api>
なお macOS のターミナルで実行する際には,?page=2
ではなく \?page=2
のようにエスケープして入力する必要があることに注意してください.これは macOS で http
コマンドを利用する際も同様です.
(py310) rinsaka@MacBookAir2023 django_comment_api % curl http://127.0.0.1:8000/comments/ ⏎ {"count":12,"next":"http://127.0.0.1:8000/comments/?page=2","previous":null,"results":[{"id":14,"title":"API edit","body":"post edit","updated_at":"2023-11-21T22:25:10.298497"},{"id":12,"title":"API","body":"post","updated_at":"2023-11-21T22:21:00.087666"}]}% (py310) rinsaka@MacBookAir2023 django_comment_api % (py310) rinsaka@MacBookAir2023 django_comment_api % curl http://127.0.0.1:8000/comments/\?page=2 ⏎ {"count":12,"next":"http://127.0.0.1:8000/comments/?page=3","previous":"http://127.0.0.1:8000/comments/","results":[{"id":11,"title":"abc","body":"aaaa","updated_at":"2023-11-21T22:13:29.401861"},{"id":10,"title":"10個目のコメント","body":"コメントの本文101","updated_at":"2023-11-21T22:06:42.241213"}]}% (py310) rinsaka@MacBookAir2023 django_comment_api % curl http://127.0.0.1:8000/comments/\?page=3 ⏎ {"count":12,"next":"http://127.0.0.1:8000/comments/?page=4","previous":"http://127.0.0.1:8000/comments/?page=2","results":[{"id":9,"title":"9個目のコメント","body":"コメントの本文9","updated_at":"2023-11-21T11:20:00"},{"id":8,"title":"8個目のコメント","body":"コメントの本文8","updated_at":"2023-11-21T11:08:00"}]}% (py310) rinsaka@MacBookAir2023 django_comment_api %
続いて Web ブラウザから API に接続します.一覧表示では2件だけが取得されており,ページの切り替えリンクも正しく動作していることを確認します.
2ページ目に移動できました.