Skip to content

Easy way to return paginated querysets #6

@njncalub

Description

@njncalub

Is your feature request related to a problem? Please describe.

I'm looking for an easy and customizable way to return the paginated results to our endpoints.

curl 'http://localhost:5000/api/todo/?done=false&limit=5&offset=10'
{
  "count": 12,
  "limit": 5,
  "offset": 10,
  "results": [
    {
      "id": "5af24d6363f52000045bae0e",
      "text": "Suomio kvanto sh mil, krom manier sub id.",
      "done": false
    },
    {
      "id": "5af24d6363f52000045bae0f",
      "text": "Oid kv resti faras akuzativo.",
      "done": false
    }
  ]
}

There's an existing SomeModel.objects.paginate(page=1, per_page=20) that returns a Pagination object. Maybe we can utilize that?

Describe the solution you'd like

The most elegant way might be to use decorators:

@paginate(serializer=TodoType)
def list_items(done: http.QueryParam):
    if done:
        done = json.loads(done)
        return TodoModel.objects.filter(done=done)
    return TodoModel.objects.all()

But this approach mutates the function and the type annotations. This is also a little hacky since the decorator should find a way to get the limit and offset during wrapping.

Describe alternatives you've considered
We can create a PaginationComponent for the pagination settings and this also handles the limit and offset from QueryParams automatically:

def list_items(done: http.QueryParam, pgn: Pagination) -> Paginated[TodoType]:
    if done:
        queryset = TodoModel.objects(done=json.loads(done))
    else:
        queryset = TodoModel.objects.all()
    return pgn.paginate(queryset, serializer=TodoType)  # pgn should get the `limit` and `offset` automatically

Or just add it as a QuerySet method:

def list_items(done: http.QueryParam, limit: http.QueryParam, offset: http.QueryParam) -> Paginated[TodoType]:
    if done:
        queryset = TodoModel.objects(done=json.loads(done))
    else:
        queryset = TodoModel.objects.all()
    limit = json.loads(limit) or 10
    offset = json.loads(offset) or 0
    return queryset.paginated(serializer=TodoType, limit=limit, offset=offset)

Additional context

Still open for suggestions

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions