Django and Pagination
本サイトに使ったfetchするurlを相対的に指定するCursorPaginationのメモです。 次のDjangoのPaginationのうち、データ更新が頻繁なアプリにはカーソル型が適しています。
- PageNumberPagination
e.g. ~/?page=4 - LimitOffsetPagination
e.g. ~/?limit=5&offset=400 - CursorPagination
e.g. ~/?cursor=cj0xJnA9MjAxOC
ref
viewsetに適用する
ListViewsetなどでは、pagination_classを指定するだけで完了します。
今回はテンプレートを利用していないため、自分でページネーションを適用します。
後半の関数引数requestは、各クラスにrequestを与えるためあとでオーバーライドさせます。
class CustomViewSet (GenericViewSet):
queryset = CustomModel.objects.all() # CustomModelは別で定義
serializer_class = CustomSerializer # CustomSerializerは後で定義
pagination_class = CustomPagination # CustomPaginationは後で定義
def list (self, request):
queryset = self.filter_queryset( self.get_queryset() )
paginate = self.paginate_qeryset(objs)
if paginate is None:
return self.get_paginated_response(None , request=request)
data = self.get_serializer(paginate, many=True, request=request)
return self.get_paginated_response(data.data , request=request)
ViewsetのResponseを拡張する
GenericViewSetで定義されているself.get_paginated_responseのソースコードを確認すると、
self.paginatorの値を参照し,Dictを返しているだけなので、簡単にオーバーライドできます。
第二引数にrequestを指定することで、アクセスしたユーザー情報によってResponseを指定できます。
class CustomViewSet (GenericViewSet):
...
def get_paginated_response(self, data, request=None):
return Response({
'next' : self.paginator.get_next_link() if data else None,
'previous': self.paginator.get_previous_link() if data else None,
'results' : data if data else "Page Not found.",
'isAuth' : True if request.user else False,
}, status = 404 if data is None else 200)