django-ninja-extra icon indicating copy to clipboard operation
django-ninja-extra copied to clipboard

How to make Paginated response from queryset ?

Open Elixir-MeetThoriya opened this issue 1 year ago • 4 comments

   @http_get(
        path="",
        response={
            HTTPStatus.OK: PaginatedResponseSchema[CountrySchema] | List[CountrySchema],
            HTTPStatus.INTERNAL_SERVER_ERROR: ErrorSchema
        },
        summary="Country List",
        description="This endpoint retrieves a list of countries.",
        url_name="country_list"
    )
    # @paginate()  # use default pagination (which define in setting.py)
    @ordering(Ordering, ordering_fields=['name', 'code'])
    @searching(Searching, search_fields=['name', 'code'])
    def list(self):
        try:
            if self.request.headers.get('no_page') == 1:
                return self.model.objects.all()
            else:
                return .................

Hiiii @eadwinCode this is my list api .. default pagination class = from ninja_extra.pagination import PageNumberPaginationExtra i need to send condition base response (paginated or non-paginated) so in my list api-function how to make a paginated response, without using "@paginate" decorator.

Elixir-MeetThoriya avatar Oct 24 '24 10:10 Elixir-MeetThoriya

@Elixir-MeetThoriya you can make your API function by return paginated response by returning PaginatedResponseSchema instance

...
items = list(self.mode.objects.all()
return PaginatedResponseSchema[CountrySchema](count=len(items), results=items, next=None, previous=None)

eadwinCode avatar Nov 01 '24 03:11 eadwinCode

@eadwinCode i know this way but i think is not proper way , because if we use return return PaginatedResponseSchema[CountrySchema](count=len(items), results=items, next=None, previous=None)

pagination not work.

please give me another way which use default paginate/pagination functionality.

    @http_get(
        path="",
        response={
            HTTPStatus.OK: PaginatedResponseSchema[ActivitySchema] | List[ActivitySchema],
            HTTPStatus.INTERNAL_SERVER_ERROR: ErrorSchema
        },
        summary="Activity List",
        description="This endpoint retrieves a list of activity.",
        url_name="activity_list"
    )
    # @paginate()
    @ordering(Ordering, ordering_fields=['name'])
    @searching(Searching, search_fields=['name'])
    def list(self):
        try:
            if self.request.headers.get('no_page') == 1:
                 return self.model.objects.all()
            else:
                 # return super().list(filter_kwargs={'center_id': self.center_id})
                 qs = list(self.model.objects.all())
                 return PaginatedResponseSchema[ActivitySchema](count=len(qs), results=qs, next=None, previous=None)

Elixir-MeetThoriya avatar Nov 07 '24 10:11 Elixir-MeetThoriya

hi @Elixir-MeetThoriya, I'm not sure about the correctness, but I can give it a try in this form

def list(self):
    try:
        no_page = self.request.headers.get('no_page') == '1'

        def get_queryset():
            return self.model.objects.all()

        if no_page:
            return get_queryset()
        else:
            paginated_func = paginate()(get_queryset)
            return paginated_func()

Aidan79225 avatar May 04 '25 02:05 Aidan79225

Another way is to write a custom pagination class with paginate_queryset that injected with a request

Aidan79225 avatar May 04 '25 04:05 Aidan79225