0

I'm using Django for my work project. What I need to get is all likes put by some user. Likes are put to transactions, so I am getting the list of all transactions in 'items' field, where the user put his like/dislike. There are some optional parameters that can be in the request:

{
"user_id": (usually is taken from session but can be used to get likes of specific user by admins), 
"like_kind_id": (1 for like/2 for dislike), 
"include_code_and_name": (True/False), 
"page_size": (integer number) for pagination
}

With the last parameter, I am facing the issues. The result should look like this:

{
​  "user_id":id,
​  "likes":[
​  {
    "like_kind":{
      "id":id,
      "code":like_code,
      "name":like_name,
    },
    "items":[
    {
      "transaction_id":transaction_id,
      "time_of":date_created,
    },...
    ]
  }
  ]
}

"Likes" is just array of 2 elements (like and dislike). So, my problem is that I cannot set pagination for "items" array as there can be a lot of transactions. I am getting the page_size from request.data.get("page_size") but cannot apply it so that the results will be paginated. I know that for GET-requests I need simply set pagination_class in views.py. Anyone knows how can I do the similar procedure for POST-request and set the page_size of pagination class to 'page_size' from data.request? =)

This is my 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)

My 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']

In urls.py I have the following path:


path('get-likes-by-user/', likes_views.LikesUserListAPIView.as_view()),

If you have any questions, please ask. Thanks, all!! I will appreciate your help!

  • Does this answer your question? [Django Rest Framework - APIView Pagination](https://stackoverflow.com/questions/35830779/django-rest-framework-apiview-pagination) – NKSM Sep 06 '22 at 10:43
  • A POST request is used to *change state*, hence paginating does not make much sense. – Willem Van Onsem Sep 06 '22 at 10:45
  • @WillemVanOnsem, but I am getting some results after making such request. – Talgat Bektleuov Sep 06 '22 at 11:55
  • @TalgatBekteuolev: then you either should list all data, or make an endpoint for a GET request that can do pagination. But the idea of a POST request is that the state changes, so typically making an extra POST request, will make another change, so then that is not the same "results" that are displayed, – Willem Van Onsem Sep 06 '22 at 11:58
  • @NKSM, I guess your link to the question is about GET-request, I tried to apply the same procedure to my post() method but it didn't work.. anyway thanks! – Talgat Bektleuov Sep 06 '22 at 12:17
  • Seems like I really have to use GET-request and put my parameters in the url like this: /get-likes-by-user?user_id=1&page_size=5. Thanks everyone, now I will modify my code! – Talgat Bektleuov Sep 06 '22 at 17:35

0 Answers0