Skip to content

Add pagination helpers #5

Description

@senko

Django's built-in paginator works in terms of fixed-size pages. While usable in API context, this might pose problems if results are likely to change between subsequent page requests (eg. more data pours in).

A simple pagination model with since (all objects after the selected one) and limit works better in this case. Here's a sample implementation:

def get_paginated_data(data, start, count, order='-id'):
    if order.startswith('-'):
        asc = False
        order_field = order[1:]
    else:
        asc = True
        order_field = order

    ordered_data = data.order_by(order)
    if start:
        filter_fields = {
            order_field + ('__gte' if asc else '__lte'): start
        }
        ordered_data = ordered_data.filter(**filter_fields)

    retval = list(ordered_data[:count + 1])
    if len(retval) > count:
        obj = retval[count]
        while '__' in order_field:
            prefix, order_field = order_field.split('__', 1)
            obj = getattr(obj, prefix)
        next = getattr(obj, order_field)
        retval = retval[:-1]
    else:
        next = None

    return (retval, next)

Note that this example includes the "since" object in results (in effect, returning it twice).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions