Какой атрибут в представлении позволяет настроить пагинацию
Перейти к содержимому

Какой атрибут в представлении позволяет настроить пагинацию

  • автор:

Pagination

Pagination – это компонент, используемый для загрузки данных по страницам. Это позволяет пользователям осуществлять навигацию по большому объему данных с предсказуемой производительностью.

См. также компонент SimplePagination, который имеет другое визуальное представление и может использоваться внутри Table , DataGrid и других компонентов-списков.

XML-имя компонента: pagination .

Основы

Pagination содержит номера страниц, что позволяет пользователю выбрать определенную страницу, и выпадающий список для выбора количества элементов на странице.

Чтобы использовать разбивку на страницы вместе с компонентом-списком, необходимо привязать компонент Pagination и компонент-список к одному и тому же источнику данных.

pagination

Привязка к данным

Чтобы создать Pagination , связанный с данными, используйте вложенный элемент containerProvider или loaderProvider .

У Pagination должен быть только один провайдер.

containerProvider

  (1)    (2)  
1 CollectionContainer для сущности Customer .
2 Компонент Pagination связан с источником данных с помощью атрибута dataContainer вложенного элемента containerProvider .

loaderProvider

     (1)     (2)  
1 citiesDl CollectionLoader загружает коллекцию сущностей по JPQL-запросу.
2 Компонент Pagination связан с источником данных с помощью атрибута loaderId вложенного элемента loaderProvider .

Количество элементов на странице

У Pagination есть специальный ComboBox со списком параметров для ограничения количества элементов на одной странице. Чтобы сделать его видимым, установите для атрибута itemsPerPageVisible значение true . Значение по умолчанию – false .

pagination items per page combo box

Значение по умолчанию для этого списка указано в свойстве jmix.ui.component.pagination-items-per-page-options.

Можете настроить свой список параметров, используя атрибут itemsPerPageOptions . Значением атрибута должен быть список параметров, разделенных запятыми:

Значения, меньшие или равные 0 , игнорируются. Значения, превышающие максимальное количество загружаемых записей заменяются на данное максимальное значение.

Используйте атрибут itemsPerPageDefaultValue чтобы задать значение по умолчанию из списка параметров:

Атрибут itemsPerPageUnlimitedOptionVisible задает видимость неограниченного (null) значения параметра в списке ComboBox . Значение по умолчанию – true .

Если выбран параметр null , компонент попытается загрузить все данные которые возможно при текущем ограничении на максимальное количество загружаемых записей.

Максимальное количество загружаемых записей для всех сущностей определено с помощью свойства jmix.ui.default-max-fetch-size. Значение по умолчанию для этого свойства — 10000 . У конкретной сущности может быть другое значение максимального количество загружаемых записей, заданное с помощью свойства jmix.ui.entity-max-fetch-size.

Количество видимых страниц

Компонент Pagination позволяет изменять количество максимально видимых страниц с помощью атрибута maxVisiblePages . Страниц в компонент может быть много, но пользователи будут видеть сразу несколько страниц, в соответствии с атрибутом maxVisiblePages . Значение по умолчанию – 5 . Например, если установить maxVisiblePages=»3″ , будет видно только три страницы одновременно:

pagination max visible pages

События и слушатели

Чтобы сгенерировать заглушку слушателя в Jmix Studio, выберите компонент в XML-дескрипторе экрана или на панели иерархии Jmix UI и используйте вкладку Handlers на панели инспектора Jmix UI.

В качестве альтернативы вы можете воспользоваться кнопкой Generate Handler на верхней панели контроллера экрана.

PageChangeEvent

PageChangeEvent отправляется, когда пользователь выбирает другую страницу или нажимает на кнопки навигации (следующая, предыдущая и т.д.).

Пример подписки на событие компонента Pagination , объявленного в XML с идентификатором pagination id:

@Subscribe("pagination") public void onPaginationPageChange(Pagination.PageChangeEvent event)

Чтобы создать слушателя события программно, используйте метод компонента addPageChangeListener() .

BeforeRefreshEvent

BeforeRefreshEvent отправляется перед обновлением данных, когда пользователь нажимает «следующая», «предыдущая» и т.д. Можно предотвратить обновление контейнера данных, вызвав метод preventRefresh() , например:

@Subscribe("paginationWithDefault") public void onPaginationWithDefaultBeforeRefresh(PaginationComponent.BeforeRefreshEvent event) < if (event.getSource().getDataBinder().getCount() >10) (1) event.preventRefresh(); (2) >
1 Проверьте количество экземпляров в хранилище данных.
2 Предотвратите обновление данных.

Чтобы создать слушателя события программно, используйте метод компонента addBeforeRefreshListener() .

AfterRefreshEvent

AfterRefreshEvent вызывается при обновлении данных.

Пример подписки на событие компонента Pagination , объявленного в XML с идентификатором paginationWithDefault :

@Subscribe("paginationWithDefault") public void onPaginationWithDefaultAfterRefresh(PaginationComponent.AfterRefreshEvent event)

Чтобы создать слушателя события программно, используйте метод компонента addAfterRefreshListener() .

TotalCountDelegate

TotalCountDelegate – это слушатель, который используется для получения общего количества элементов. Например:

@Install(to = "pagination", subject = "totalCountDelegate") private Integer paginationTotalCountDelegate()

Чтобы создать слушателя TotalCountDelegate программно, используйте метод setTotalCountDelegate() .

Все XML-атрибуты

Просматривать и редактировать атрибуты, применимые к компоненту, можно с помощью панели инспектора Jmix UI в конструкторе экранов Studio.

This page was built using the Antora default UI.

The source code for this UI is licensed under the terms of the MPL-2.0 license.

Добавляем пагинацию (pagination)

На этом занятии мы рассмотрим возможность разбивки списка данных на отдельные страницы. Например, у нас имеется API-запрос на список известных женщин:

Понятно, что в БД может быть огромное количество записей по женщинам и выдавать их все по данному запросу было бы крайне неразумно из-за слишком большого объема данных. Для этого и вводится пагинация, то есть, разбивка на отдельные страницы по несколько записей на каждой. И как это сделать в рамках Django REST Framework мы сейчас увидим.

Конечно, в официальной документации можно подробно почитать, как подключается пагинация к проекту:

Я прямо буду ей следовать. Фактически, все что нам нужно, это прописать в словаре REST_FRAMEWORK, следующие строчки:

REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', 'PAGE_SIZE': 2, . }

Ключ ‘DEFAULT_PAGINATION_CLASS’ позволяет задать класс пагинации, который будет применяться по умолчанию к выдаваемым спискам данных. В Django REST Framework имеется встроенный класс LimitOffsetPagination и мы его здесь указываем. Второй ключ ‘PAGE_SIZE’ задает число записей (в нашем случае женщин) на странице. Я указал два, чтобы мы могли видеть пагинацию в действии.

Запустим, теперь, тестовый веб-сервер:

python manage.py runserver

и откроем в браузере страницу:

Как видите, у нас здесь с вами отобразился только первый фрагмент списка из двух записей. Кроме того, в JSON-ответе мы видим параметры:

  • «count» – общее число записей;
  • «next» – ссылка на следующую страницу;
  • «previous» – ссылка на предыдущую страницу;
  • «results» – набор данных.

Также средства DRF позволяют нам в интерактивном режиме в браузере переключаться по страницам и просматривать их содержимое. Однако, обратите внимание, такая пагинация будет автоматически применяться к каждому API-запросу, где идет вывод списка данных. Например, у нас есть запрос для списка зарегистрированных пользователей: http://127.0.0.1:8000/api/v1/auth/users/ и здесь мы тоже видим включенный режим пагинации. Но, если открыть страницу с одной записью: http://127.0.0.1:8000/api/v1/women/9/ то никакой пагинации не будет, т.к. здесь нет списка записей в ответе.

Пользовательские классы пагинации

Конечно, нам может потребоваться для определенных API-запросов настраивать свои параметры пагинации. Это делается достаточно просто с помощью определения собственных классов пагинации и подключения их к нужным видам. Давайте сделаем это для класса WomenAPIList. Вначале определим свой класс пагинации WomenAPIListPagination, который унаследуем от базового класса в DRF – PageNumberPagination:

class WomenAPIListPagination(PageNumberPagination): page_size = 3 page_size_query_param = 'page_size' max_page_size = 10000
  • page_size – число записей на страницу;
  • page_size_query_param – параметр запроса, в котором можно настраивать количество выдаваемых записей на страницу;
  • max_page_size – максимальное количество записей на странице для запроса page_size_query_param.
class WomenAPIList(generics.ListCreateAPIView): queryset = Women.objects.all() serializer_class = WomenSerializer permission_classes = (IsAuthenticatedOrReadOnly, ) pagination_class = WomenAPIListPagination

и в браузере откроем страницу: http://127.0.0.1:8000/api/v1/women/ Видим, что выдается по три записи на странице, как это и настроено в нашем пользовательском классе. Но мы также можем выполнить и такой запрос: http://127.0.0.1:8000/api/v1/women/?page_size=4 Здесь дополнительно прописан параметр page_size со значением 4. Теперь у нас на странице будет по четыре записи. Этот параметр можно использовать, если клиент пожелает изменить число выдаваемых записей на странице. Но их будет не более max_page_size. Например, если этот параметр установить в два:

max_page_size = 2

База данных · Постраничная навигация

В других фреймворках постраничная навигация может быть очень болезненной. Мы надеемся, что подход Laravel к разбиению на страницы станет глотком свежего воздуха. Пагинатор Laravel интегрирован с построителем запросов и Eloquent ORM и обеспечивает удобную, простую в использовании разбивку на страницы записей базы данных с нулевой конфигурацией.

По умолчанию HTML, генерируемый пагинатором, совместим с фреймворком Tailwind CSS; однако, также доступна поддержка разбивки на страницы с использованием Bootstrap.

Tailwind JIT

Если вы используете стандартные представления Laravel для разбивки на страницы Tailwind и механизм JIT Tailwind, вы должны убедиться, что ключ content файла tailwind.config.js вашего приложения ссылаются на представления разбиения на страницы Laravel, чтобы их классы Tailwind не удалялись:

content: [ './resources/**/*.blade.php', './resources/**/*.js', './resources/**/*.vue', './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php', ], 

Основы использования

Разбиение результатов построителя запросов

Есть несколько способов разбить элементы на страницы. Самый простой – использовать метод paginate построителя запросов или в запросе Eloquent. Метод paginate автоматически устанавливает «предел» и «смещение» в запросе на основе текущей страницы, просматриваемой пользователем. По умолчанию текущая страница определяется значением аргумента page строки HTTP-запроса. Это значение автоматически определяется Laravel, а также автоматически вставляется в ссылки, генерируемые пагинатором.

В этом примере единственный аргумент, переданный методу paginate – это количество элементов, которые вы хотите отображать «на каждой странице». В этом случае давайте укажем, что мы хотели бы отображать 15 элементов на странице:

 namespace App\Http\Controllers; use App\Http\Controllers\Controller; use Illuminate\Support\Facades\DB; class UserController extends Controller < /** * Показать всех пользователей приложения. * * @return \Illuminate\Http\Response */ public function index() < return view('user.index', [ 'users' => DB::table('users')->paginate(15) ]); > > 
Простая пагинация

Метод paginate подсчитывает общее количество записей, соответствующих запросу, перед извлечением записей из базы данных. Это сделано для того, чтобы пагинатор знал, сколько всего страниц с записями необходимо сформировать. Однако, если вы не планируете отображать общее количество страниц в пользовательском интерфейсе вашего приложения, запрос количества записей не нужен.

Следовательно, если вам нужно отображать только простые ссылки «Далее» и «Назад» в пользовательском интерфейсе вашего приложения, вы можете использовать метод simplePaginate для выполнения одного рационального запроса:

$users = DB::table('users')->simplePaginate(15); 

Разбиение результатов Eloquent

Вы также можете разбивать запросы Eloquent на страницы. В этом примере мы разобьем модель App\Models\User на страницы и укажем, что мы планируем отображать 15 записей на странице. Как видите, синтаксис почти идентичен разбивке на страницы результатов построителя запросов:

use App\Models\User; $users = User::paginate(15); 

Конечно, вы можете вызвать метод paginate после указания других ограничений для запроса, таких как выражения where :

$users = User::where('votes', '>', 100)->paginate(15); 

Вы также можете использовать метод simplePaginate при разбиении на страницы моделей Eloquent:

$users = User::where('votes', '>', 100)->simplePaginate(15); 

Точно так же вы можете использовать метод cursorPaginate для курсорной пагинации моделей Eloquent:

$users = User::where('votes', '>', 100)->cursorPaginate(15); 
Несколько экземпляров пагинации на странице

Иногда вам может потребоваться отобразить два отдельных модуля пагинации на одном экране, который отображается вашим приложением. Однако, если оба экземпляра пагинации используют параметр строки запроса page для хранения текущей страницы, они будут конфликтовать. Чтобы разрешить этот конфликт, вы можете передать имя параметра строки запроса, который вы хотите использовать для хранения текущей страницы, через третий аргумент, предоставленный методам paginate , simplePaginate и cursorPaginate :

use App\Models\User; $users = User::where('votes', '>', 100)->paginate( $perPage = 15, $columns = ['*'], $pageName = 'users' ); 

Cursor-пагинация

В то время как paginate и simplePaginate создают запросы с использованием SQL-оператора «offset», Cursor-пагинация работает путем создания конструкции «where», которая сравнивает значения упорядоченных столбцов, содержащихся в запросе, обеспечивая наиболее эффективную производительность базы данных среди всех возможных, доступную среди всех методов пагинации Laravel. Этот метод пагинации особенно хорошо подходит для больших наборов данных и пользовательских интерфейсов с «бесконечной» прокруткой.

В отличие от пагинации на основе смещения, которая включает номер страницы в строке запроса URL-адресов, сгенерированных средством постраничной навигации, Cursor-пагинация помещает «cursor» в строку запроса. Курсор представляет собой закодированную строку, содержащую место, с которого следующий запрос с пагинацией должен начать постраничную навигацию, и направление, в котором он должен разбиваться на страницы:

http://localhost/users?cursor=eyJpZCI6MTUsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0 

Вы можете создать экземпляр Cursor-пагинации с помощью метода cursorPaginate , предлагаемого построителем запросов. Этот метод возвращает экземпляр Illuminate\Pagination\CursorPaginator :

$users = DB::table('users')->orderBy('id')->cursorPaginate(15); 

После того как вы получили экземпляр Cursor-пагинации, вы можете отобразить результаты постраничной навигации как обычно при использовании методов paginate и simplePaginate . Для получения дополнительной информации о методах экземпляра, предлагаемых средством Cursor-пагинации, обратитесь к документации по методам экземпляра Cursor Paginator.

Ваш запрос должен содержать предложение «order by», чтобы можно было использовать Cursor-пагинацию.

«Cursor» против «Offset» пагинации

Чтобы проиллюстрировать различия между «Cursor» и «Offset» постраничной навигацией, давайте рассмотрим несколько примеров SQL-запросов. Оба следующих запроса будут отображать «вторую страницу» результатов для таблицы users , упорядоченных по id :

# Offset пагинация. select * from users order by id asc limit 15 offset 15; # Cursor пагинация. select * from users where id > 15 order by id asc limit 15; 

Cursor-пагинация предлагает следующие преимущества перед Offset-пагинацией:

  • Для больших наборов данных Cursor-пагинация обеспечивать лучшую производительность, если столбцы «order by» проиндексированы. Это связано с тем, что предложение «offset» сканирует все ранее сопоставленные данные.
  • Для наборов данных с частыми записями Offset-пагинация может пропускать записи или отображать дубликаты, если результаты были недавно добавлены или удалены со страницы, которую пользователь просматривает в данный момент.

Однако, Cursor-пагинация имеет следующие ограничения:

  • Как и simplePaginate , Cursor-пагинация может использоваться только для отображения ссылок «Далее» и «Назад» и не поддерживает создание ссылок с номерами страниц.
  • Требуется, чтобы порядок был основан как минимум на одном уникальном столбце или на комбинации уникальных столбцов. Столбцы с null — значениями не поддерживаются.
  • Выражения запроса в предложениях «order by» поддерживаются только в том случае, если они имеют псевдонимы и также добавляются в предложение «select».

Самостоятельное создание пагинатора

По желанию можно вручную создать экземпляр пагинатора, передав ему массив элементов, которые у вас уже есть в памяти. Вы можете сделать это, создав экземпляр Illuminate\Pagination\Paginator , Illuminate\Pagination\LengthAwarePaginator или Illuminate\Pagination\CursorPaginator , в зависимости от ваших потребностей.

Классам Paginator и CursorPaginator не требуется знать общее количество элементов в результирующем наборе; однако, из-за этого у классов нет методов для получения индекса последней страницы. Класс LengthAwarePaginator принимает почти те же аргументы, что и Paginator ; однако, для этого требуется подсчет общего количества элементов в результирующем наборе.

Другими словами, Paginator соответствует методу simplePaginate построителя запросов, CursorPaginator соответствует методу cursorPaginate , а LengthAwarePaginator соответствует методу paginate .

При ручном создании экземпляра пагинатора вы должны самостоятельно «разрезать» массив результатов, который вы передаете в пагинатор. Если вы не знаете, как это сделать, ознакомьтесь с функцией PHP array_slice .

Настройка URL-адресов постраничной навигации

По умолчанию ссылки, созданные пагинатором, будут соответствовать URI текущего запроса. Однако метод withPath пагинатора позволяет вам скорректировать URI, используемый пагинатором при генерации ссылок. Например, если вы хотите, чтобы пагинатор генерировал ссылки типа http://example.com/admin/users?page=N , вы должны передать /admin/users withPath :

use App\Models\User; Route::get('/users', function () < $users = User::paginate(15); $users->withPath('/admin/users'); // >); 
Добавление значений в строку запроса

Вы можете добавить параметр в строку запроса навигационных ссылок с помощью метода appends . Например, чтобы добавить sort=votes к каждой ссылке пагинации, вы должны сделать следующий вызов appends :

use App\Models\User; Route::get('/users', function () < $users = User::paginate(15); $users->appends(['sort' => 'votes']); // >); 

Вы можете использовать метод withQueryString , если хотите добавить все значения строки текущего запроса к ссылкам постраничной навигации:

$users = User::paginate(15)->withQueryString(); 
Добавление фрагментов хеша

Если вам нужно добавить «хеш-фрагмент» к URL-адресам, сгенерированным пагинатором, вы можете использовать метод fragment . Например, чтобы добавить #users в конец каждой навигационной ссылки, вы должны вызвать метод fragment следующим образом:

$users = User::paginate(15)->fragment('users'); 

Отображение результатов постраничной навигации

При вызове метода paginate вы получите экземпляр Illuminate\Pagination\LengthAwarePaginator , вызов метода simplePaginate возвращает экземпляр Illuminate\Pagination\Paginator . И, наконец, вызов метода cursorPaginate возвращает экземпляр Illuminate\Pagination\CursorPaginator .

Эти объекты содержат несколько методов, описывающих результирующий набор. В дополнение к этим вспомогательным методам, экземпляры пагинатора являются итераторами и могут быть перебраны как массив. Итак, как только вы получили результаты, вы можете отобразить результаты и отрисовать ссылки на страницы, используя Blade:

div class="container"> @foreach ($users as $user) name >> @endforeach div> links() >> 

Метод links отрисует ссылки на остальные страницы в результирующем наборе. Каждая из этих ссылок уже будет содержать соответствующую строковую переменную запроса page . Помните, что HTML, сгенерированный методом links , совместим с фреймворком Tailwind CSS.

Регулирование количества отображаемых ссылок

Когда пагинатор отображает навигационные ссылки, включающие номер текущей страницы, а также ссылки для трех страниц до и после текущей. Используя метод onEachSide , вы можете контролировать, сколько дополнительных ссылок отображается с каждой стороны от текущей страницы в среднем скользящем окне ссылок, созданных пагинатором:

onEachSide(5)->links() >> 

Преобразование результатов в JSON

Классы пагинатора Laravel реализуют контракт интерфейса Illuminate\Contracts\Support\Jsonable и содержат метод toJson , поэтому очень легко преобразовать результаты в JSON. Вы также можете преобразовать экземпляр пагинатора в JSON, вернув его из маршрута или действия контроллера:

use App\Models\User; Route::get('/users', function () < return User::paginate(); >); 

JSON из пагинатора будет включать метаинформацию, такую как total , current_page , last_page и другие. Записи результатов доступны через ключ data в массиве JSON. Вот пример JSON, созданного путем возврата экземпляра пагинатора из маршрута:

< "total": 50, "per_page": 15, "current_page": 1, "last_page": 4, "first_page_url": "http://laravel.app?page=1", "last_page_url": "http://laravel.app?page=4", "next_page_url": "http://laravel.app?page=2", "prev_page_url": null, "path": "http://laravel.app", "from": 1, "to": 15, "data":[ < // Запись . >, < // Запись . > ] > 

Настройка вида пагинации

По умолчанию сгенерированные шаблоны для отображения навигационных ссылок, совместимы со структурой фреймворка Tailwind CSS. Однако, если вы не используете Tailwind, вы можете определять свои собственные шаблоны для отображения этих ссылок. При вызове метода links в экземпляре пагинатора вы можете передать имя шаблона в качестве первого аргумента метода:

links('view.name') >> // Передача дополнительных данных в шаблон . links('view.name', ['foo' => 'bar']) >> 

Однако, самый простой способ отредактировать шаблоны постраничной навигации – это экспортировать их в каталог resources/views/vendor с помощью команды vendor:publish :

php artisan vendor:publish --tag=laravel-pagination 

Эта команда поместит шаблоны в каталог resources/views/vendor/pagination вашего приложения. Файл tailwind.blade.php в этом каталоге соответствует шаблону постраничной навигации по умолчанию. Вы можете отредактировать этот файл для изменения HTML-кода навигации.

Если вы хотите назначить другой файл в качестве шаблона постраничной навигации по умолчанию, вы можете вызвать методы defaultView и defaultSimpleView пагинатора в методе boot вашего класса App\Providers\AppServiceProvider :

 namespace App\Providers; use Illuminate\Pagination\Paginator; use Illuminate\Support\Facades\Blade; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider < /** * Загрузка любых служб приложения. * * @return void */ public function boot() < Paginator::defaultView('view-name'); Paginator::defaultSimpleView('view-name'); > > 

Использование Bootstrap

Laravel содержит шаблоны постраничной навигации, созданные с использованием Bootstrap CSS. Чтобы использовать эти шаблоны вместо шаблонов Tailwind по умолчанию, вы можете вызвать метод пагинатора useBootstrap в методе boot класса App\Providers\AppServiceProvider :

use Illuminate\Pagination\Paginator; /** * Загрузка любых служб приложения. * * @return void */ public function boot()  

Методы экземпляра Paginator и LengthAwarePaginator

Каждый экземпляр пагинатора содержит дополнительную информацию о постраничной навигации с помощью следующих методов:

Метод Описание
$paginator->count() Получить количество элементов для текущей страницы.
$paginator->currentPage() Получить номер текущей страницы.
$paginator->firstItem() Получить номер первого элемента в результатах.
$paginator->getOptions() Получить параметры пагинатора.
$paginator->getUrlRange($start, $end) Создать диапазон URL-адресов для пагинации.
$paginator->hasPages() Определить, достаточно ли элементов для разделения на несколько страниц.
$paginator->hasMorePages() Определить, есть ли еще элементы в хранилище данных.
$paginator->items() Получить элементы для текущей страницы.
$paginator->lastItem() Получить номер последнего элемента в результатах.
$paginator->lastPage() Получить номер последней доступной страницы. (Недоступно при использовании simplePaginate ).
$paginator->nextPageUrl() Получить URL-адрес следующей страницы.
$paginator->onFirstPage() Определить, находится ли пагинатор на первой странице.
$paginator->perPage() Количество элементов, отображаемых на каждой странице.
$paginator->previousPageUrl() Получить URL-адрес предыдущей страницы.
$paginator->total() Определить общее количество элементов запроса в хранилище данных. (Недоступно при использовании simplePaginate ).
$paginator->url($page) Получить URL-адрес для конкретного номера страницы.
$paginator->getPageName() Получить переменную строки запроса, используемую для хранения страницы.
$paginator->setPageName($name) Установить переменную строки запроса, используемую для хранения страницы.

Методы экземпляра Cursor Paginator

Каждый экземпляр Cursor-пагинатора предоставляет дополнительную информацию о постраничной навигации с помощью следующих методов:

Method Description
$paginator->count() Получить количество элементов для текущей страницы.
$paginator->cursor() Получить текущий экземпляр курсора.
$paginator->getOptions() Получить параметры пагинатора.
$paginator->hasPages() Определить, достаточно ли элементов для разделения на несколько страниц.
$paginator->hasMorePages() Определить, есть ли еще элементы в хранилище данных.
$paginator->getCursorName() Получить переменную строки запроса, используемую для хранения курсора.
$paginator->items() Получить элементы для текущей страницы.
$paginator->nextCursor() Получить экземпляр курсора для следующего набора элементов.
$paginator->nextPageUrl() Получить URL-адрес следующей страницы.
$paginator->onFirstPage() Определить, находится ли пагинатор на первой странице.
$paginator->perPage() Количество элементов, отображаемых на каждой странице.
$paginator->previousCursor() Получите экземпляр курсора для предыдущего набора элементов.
$paginator->previousPageUrl() Получить URL-адрес предыдущей страницы.
$paginator->setCursorName() Установить переменную строки запроса, используемую для хранения курсора.
$paginator->url($cursor) Получить URL-адрес для данного экземпляра курсора.
Русскоязычное комьюнити
  • Группа в VK
  • Телеграм LaravelRUS
  • Телеграм Laravel для новичков
  • Телеграм LaravelPro
Обучающие ресурсы
  • Laracasts
  • Codecourse
  • Курс Дмитрия Елисеева
  • Adam Wathan
Блоги разработчиков
  • Laravel News
  • Freek Van der Herten
  • Brent Roose
  • Marcel Pociot

Пагинация¶

Django предоставляет высокоуровневые и низкоуровневые способы управления постраничными данными — то есть данными, разделенными на несколько страниц, со ссылками «Предыдущая/Следующая».

Класс Paginator ¶

Под капотом все методы пагинации используют класс Paginator . Он выполняет всю тяжелую работу по разбиению QuerySet на Page объекты.

Пример¶

Дайте Paginator список объектов, плюс количество элементов, которые вы хотели бы иметь на каждой странице, и он предоставит вам методы для доступа к элементам для каждой страницы:

>>> from django.core.paginator import Paginator >>> objects = ["john", "paul", "george", "ringo"] >>> p = Paginator(objects, 2) >>> p.count 4 >>> p.num_pages 2 >>> type(p.page_range) >>> p.page_range range(1, 3) >>> page1 = p.page(1) >>> page1 >>> page1.object_list ['john', 'paul'] >>> page2 = p.page(2) >>> page2.object_list ['george', 'ringo'] >>> page2.has_next() False >>> page2.has_previous() True >>> page2.has_other_pages() True >>> page2.next_page_number() Traceback (most recent call last): . EmptyPage: That page contains no results >>> page2.previous_page_number() 1 >>> page2.start_index() # The 1-based index of the first item on this page 3 >>> page2.end_index() # The 1-based index of the last item on this page 4 >>> p.page(0) Traceback (most recent call last): . EmptyPage: That page number is less than 1 >>> p.page(3) Traceback (most recent call last): . EmptyPage: That page contains no results 

Обратите внимание, что вы можете передать Paginator список/кортеж, Django QuerySet или любой другой объект с методом count() или __len__() . При определении количества объектов, содержащихся в переданном объекте, Paginator сначала попытается вызвать count() , затем вернется к использованию len() , если у переданного объекта нет метода count() . Это позволяет таким объектам, как QuerySet Django, использовать более эффективный count() метод, если он доступен.

Пагинация ListView ¶

django.views.generic.list.ListView предоставляет встроенный способ постраничного отображения списка. Вы можете сделать это, добавив атрибут paginate_by к вашему классу представления, например:

from django.views.generic import ListView from myapp.models import Contact class ContactListView(ListView): paginate_by = 2 model = Contact 

Это ограничивает количество объектов на странице и добавляет paginator и page_obj к context . Чтобы пользователи могли перемещаться между страницами, добавьте ссылки на следующую и предыдущую страницу в ваш шаблон следующим образом:

 for contact in page_obj %>  contact.full_name|upper >>br> .  endfor %> div class="pagination"> span class="step-links">  if page_obj.has_previous %> a href="?page=1">« firsta> a href="?page= page_obj.previous_page_number >>">previousa>  endif %> span class="current"> Page  page_obj.number >> of  page_obj.paginator.num_pages >>. span>  if page_obj.has_next %> a href="?page= page_obj.next_page_number >>">nexta> a href="?page= page_obj.paginator.num_pages >>">last »a>  endif %> span> div> 

Использование Paginator в функции представления¶

Вот пример использования Paginator в функции представления для постраничного просмотра набора запросов:

from django.core.paginator import Paginator from django.shortcuts import render from myapp.models import Contact def listing(request): contact_list = Contact.objects.all() paginator = Paginator(contact_list, 25) # Show 25 contacts per page. page_number = request.GET.get("page") page_obj = paginator.get_page(page_number) return render(request, "list.html", "page_obj": page_obj>) 

В шаблоне list.html можно включить навигацию между страницами таким же образом, как и в шаблоне для ListView выше.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *