Пагинация ответа на POST-запрос в Django
Я использую Django для своего рабочего проекта. Мне нужно получить все лайки, поставленные некоторым пользователем. Лайки ставятся в транзакциях, поэтому я получаю список всех транзакций в поле 'items', где пользователь ставил лайк/не лайк. Есть несколько необязательных параметров, которые могут быть в запросе: user_id (обычно берется из сессии), like_kind_id (1 для like/2 для dislike), include_code_and_name для like_kind (True/False), и page_size (целое число) для пагинации. С последним параметром у меня возникают проблемы. Результат должен выглядеть следующим образом:
{
"user_id":id,
"likes":[
{
"like_kind":{
"id":id,
"code":like_code,
"name":like_name,
},
"items":[
{
"transaction_id":transaction_id,
"time_of":date_created,
},...
]
}
]
}
"Likes" - это просто массив из 2 элементов (нравится и не нравится). Итак, моя проблема в том, что я не могу установить пагинацию для массива "items", так как там может быть много операций. Я получаю размер страницы из request.data.get("page_size"), но не могу применить его так, чтобы результаты были постраничными. Я знаю, что для GET-запросов мне нужно просто установить pagination_class в views.py. Кто-нибудь знает, как я могу проделать аналогичную процедуру для POST-запроса и установить page_size класса pagination в 'page_size' из data.request? =)
Это мой views.py:
class LikesUserPaginationAPIView(PageNumberPagination):
page_size = 1
page_size_query_param = 'page_size'
max_page_size = 1
class LikesUserListAPIView(APIView):
"""
All likes of the user
"""
permission_classes = [IsAuthenticated]
authentication_classes = [authentication.SessionAuthentication,
authentication.TokenAuthentication]
pagination_class = LikesUserPaginationAPIView
@classmethod
def post(cls, request, *args, **kwargs):
like_kind = request.data.get('like_kind')
include_code = request.data.get('include_code')
page_size = request.data.get('page_size')
pagination.PageNumberPagination.page_size = page_size
if include_code is None:
include_code = False
else:
if include_code == "False":
include_code = False
elif include_code == "True":
include_code = True
else:
return Response("Should be True или False for include_code",
status=status.HTTP_400_BAD_REQUEST)
if like_kind is None:
like_kind = "all"
else:
try:
likekind = LikeKind.objects.get(id=like_kind)
except LikeKind.DoesNotExist:
return Response("ID doesn't exists ",
status=status.HTTP_404_NOT_FOUND)
context = {"include_code": include_code, "like_kind": like_kind}
user_id = request.user.id # get the user_id from session
# TODO
# optionally other users with higher privilege can get access to other users' likes
# need to check for the privilege (admin, coordinator, ..)
# user_id = request.data.get('user_id')
if user_id is not None:
try:
user = User.objects.get(id=user_id)
users = [user, user, user, user, user]
serializer = LikeUserSerializer(users, many=True, context=context)
return Response(serializer.data)
except User.DoesNotExist:
return Response("ID doesn't exists ",
status=status.HTTP_404_NOT_FOUND)
return Response("user_id is not given",
status=status.HTTP_400_BAD_REQUEST)
Мой serializer.py:
class LikeUserSerializer(serializers.ModelSerializer):
likes = serializers.SerializerMethodField()
user_id = serializers.SerializerMethodField()
def get_user_id(self, obj):
return obj.id
def get_likes(self, obj):
include_code = self.context.get('include_code')
like_kind_id = self.context.get('like_kind')
likes = []
if like_kind_id == "all":
like_kinds = [(like_kind.id, like_kind.name, like_kind.get_icon_url()) for like_kind in LikeKind.objects.all()]
else:
like_kinds = [(like_kind.id, like_kind.name, like_kind.get_icon_url()) for like_kind in
[LikeKind.objects.get(id=like_kind_id)]]
# {"user_id": 1}
if include_code:
for like_kind in like_kinds:
items = []
transactions_liked = [(like.transaction_id, like.date_created)
for like in Like.objects.filter_by_user_and_like_kind(obj.id, like_kind[0])]
for transaction1 in transactions_liked:
items.append(
{
"transaction_id": transaction1[0],
"time_of": transaction1[1],
}
)
likes.append(
{
"like_kind": {
'id': like_kind[0],
'name': like_kind[1],
'icon': like_kind[2],
},
"items": items
}
)
return likes
else:
for like_kind in like_kinds:
items = []
transactions_liked = [(like.transaction_id, like.date_created)
for like in Like.objects.filter_by_user_and_like_kind(obj.id, like_kind[0])]
for transaction1 in transactions_liked:
items.append(
{
"transaction_id": transaction1[0],
"time_of": transaction1[1],
}
)
likes.append(
{
"like_kind": {
'id': like_kind[0],
},
"items": items
}
)
return likes
class Meta:
model = Like
fields = ['user_id', 'likes']
В urls.py у меня есть следующий путь:
path('get-likes-by-user/', likes_views.LikesUserListAPIView.as_view()),
Если у вас есть какие-либо вопросы, пожалуйста, задавайте. Спасибо!!! Буду признателен за помощь!!!