from django.core.paginator import Paginator PAGE_SIZE_CHOICES = [10, 15, 25, 100] DEFAULT_PAGE_SIZE = 25 def _fallback_size(request, default_size): """Розмір сторінки, коли в GET нічого не передано: персональна настройка користувача (Employee.default_page_size), якщо вона задана і валідна, інакше default_size, переданий конкретним view.""" user = getattr(request, 'user', None) user_size = getattr(user, 'default_page_size', None) if user and user.is_authenticated else None return user_size if user_size in PAGE_SIZE_CHOICES else default_size def paginate(request, queryset, default_size=DEFAULT_PAGE_SIZE, page_param='page', size_param='per_page'): """ Постраничная разбивка queryset/list по GET-параметрам page_param/size_param. Размер страницы ограничен PAGE_SIZE_CHOICES (10/15/25/100) — произвольные значения из строки запроса откатываются на default_size. Именованные page_param/size_param позволяют держать на одной странице несколько независимо пагинируемых таблиц (например tickets_page, tickets_per_page). Если size_param в запросе не передан явно (обычная навигация, не смена размера страницы через селектор), используется персональная настройка пользователя (Employee.default_page_size), заданная на /settings/. """ raw = request.GET.get(size_param) if raw is None: raw = _fallback_size(request, default_size) try: per_page = int(raw) except (TypeError, ValueError): per_page = default_size if per_page not in PAGE_SIZE_CHOICES: per_page = default_size paginator = Paginator(queryset, per_page) return paginator.get_page(request.GET.get(page_param, 1))