FossilRepo
| c588255… | ragelink | 1 | """Shared pagination helpers used across all list views.""" |
| c588255… | ragelink | 2 | |
| c588255… | ragelink | 3 | import math |
| c588255… | ragelink | 4 | |
| c588255… | ragelink | 5 | PER_PAGE_OPTIONS = [25, 50, 100] |
| c588255… | ragelink | 6 | |
| c588255… | ragelink | 7 | |
| c588255… | ragelink | 8 | def get_per_page(request, default=25): |
| c588255… | ragelink | 9 | """Get per_page from request, constrained to PER_PAGE_OPTIONS.""" |
| c588255… | ragelink | 10 | try: |
| c588255… | ragelink | 11 | per_page = int(request.GET.get("per_page", default)) |
| c588255… | ragelink | 12 | except (ValueError, TypeError): |
| c588255… | ragelink | 13 | per_page = default |
| c588255… | ragelink | 14 | return per_page if per_page in PER_PAGE_OPTIONS else default |
| c588255… | ragelink | 15 | |
| c588255… | ragelink | 16 | |
| c588255… | ragelink | 17 | def manual_paginate(items, request, per_page=None): |
| c588255… | ragelink | 18 | """Paginate a plain list and return (sliced_items, pagination_dict). |
| c588255… | ragelink | 19 | |
| c588255… | ragelink | 20 | The pagination dict has keys compatible with the _pagination_manual.html partial: |
| c588255… | ragelink | 21 | has_previous, has_next, previous_page_number, next_page_number, number, num_pages, count. |
| c588255… | ragelink | 22 | """ |
| c588255… | ragelink | 23 | if per_page is None: |
| c588255… | ragelink | 24 | per_page = get_per_page(request) |
| c588255… | ragelink | 25 | total = len(items) |
| c588255… | ragelink | 26 | num_pages = max(1, math.ceil(total / per_page)) |
| c588255… | ragelink | 27 | try: |
| c588255… | ragelink | 28 | page = int(request.GET.get("page", 1)) |
| c588255… | ragelink | 29 | except (ValueError, TypeError): |
| c588255… | ragelink | 30 | page = 1 |
| c588255… | ragelink | 31 | page = max(1, min(page, num_pages)) |
| c588255… | ragelink | 32 | offset = (page - 1) * per_page |
| c588255… | ragelink | 33 | sliced = items[offset : offset + per_page] |
| c588255… | ragelink | 34 | pagination = { |
| c588255… | ragelink | 35 | "has_previous": page > 1, |
| c588255… | ragelink | 36 | "has_next": offset + per_page < total, |
| c588255… | ragelink | 37 | "previous_page_number": page - 1, |
| c588255… | ragelink | 38 | "next_page_number": page + 1, |
| c588255… | ragelink | 39 | "number": page, |
| c588255… | ragelink | 40 | "num_pages": num_pages, |
| c588255… | ragelink | 41 | "count": total, |
| c588255… | ragelink | 42 | } |
| c588255… | ragelink | 43 | return sliced, pagination |