Вопрос:

Django paginator со многими страницами

python django python-3.x pagination django-views

1777 просмотра

1 ответ

584 Репутация автора

Я реализовал paginator с помощью общего ListView. Моя проблема в том, что для списка с большим количеством страниц он отображает все номера страниц вместо, например, пяти страниц до и после текущей страницы. Есть ли простой способ это исправить?

в views.py:

class CarList(LoginRequiredMixin, ListView):
model = Car
paginate_by = 20

в HTML:

{% if is_paginated %}
        <ul class="pagination pagination-centered">
            {% if page_obj.has_previous %}
                <li><a href="/car?ordering={{ current_order }}&page=1"><<</a></li>
                <li><a href="/car?ordering={{ current_order }}&page={{ page_obj.previous_page_number }}"><</a></li>
            {% endif %}

            {% for i in paginator.page_range %}
            <li {% if page_obj.number == i %} class="active" {% endif %}><a href="/car?ordering={{ current_order }}&page={{i}}">{{i}}</a></li>
            {% endfor %}

            {% if page_obj.has_next %}
                <li><a href="/car?ordering={{ current_order }}&page={{ page_obj.next_page_number }}">></a></li>
                <li><a href="/car?ordering={{ current_order }}&page={{ page_obj.paginator.num_pages }}">>></a></li>
            {% endif %}
        </ul>
{% endif %}
Автор: Wessi Источник Размещён: 22.08.2016 09:13

Ответы (1)


11 плюса

2970 Репутация автора

Решение

Алгоритм для этого не слишком сложен, и его можно еще больше упростить, если предположить, что если имеется более 11 страниц (текущей, 5 до, 5 после), мы всегда будем показывать 11 ссылок. Теперь у нас есть 4 случая:

  1. Количество страниц <11: показать все страницы;
  2. Текущая страница <= 6: показать первые 11 страниц;
  3. Текущая страница> 6 и <(количество страниц - 6): показать текущую страницу, 5 до и 5 после;
  4. Текущая страница> = (количество страниц -6): показать последние 11 страниц.

Учитывая вышесказанное, давайте изменим ваше представление, создадим переменную для хранения количества отображаемых страниц и поместим ее в контекст:

class CarList(LoginRequiredMixin, ListView):
    model = Car
    paginate_by = 20

    def get_context_data(self, **kwargs):
        context = super(CarList, self).get_context_data(**kwargs)
        if not context.get('is_paginated', False):
            return context

        paginator = context.get('paginator')
        num_pages = paginator.num_pages
        current_page = context.get('page_obj')
        page_no = current_page.number

        if num_pages <= 11 or page_no <= 6:  # case 1 and 2
            pages = [x for x in range(1, min(num_pages + 1, 12))]
        elif page_no > num_pages - 6:  # case 4
            pages = [x for x in range(num_pages - 10, num_pages + 1)]
        else:  # case 3
            pages = [x for x in range(page_no - 5, page_no + 6)]

        context.update({'pages': pages})
        return context

Теперь вы можете просто использовать новую переменную в своем шаблоне для создания ссылок на страницы:

            (...)
            {% for i in pages %}
            <li {% if page_obj.number == i %} class="active" {% endif %}><a href="/car?ordering={{ current_order }}&page={{i}}">{{i}}</a></li>
            {% endfor %}
            (...)
Автор: rafalmp Размещён: 23.08.2016 01:16
Вопросы из категории :
32x32