Как преобразовать шаблон django для использования серверной пагинации bootstrap-table
У меня есть несколько страниц, отображаемых шаблонами django, к которым я применил bootstrap-table для реализации переключения колонок, пагинации на стороне клиента и многоколоночной сортировки. Это было сделано после создания полностью функционирующего шаблона django.
Мои таблицы очень большие, и каждый столбец имеет несколько манипуляций, например:
- ссылки на другие страницы сайта
- форматирование чисел
- выравнивание по горизонтали (например, выравнивание чисел по правому краю)
- сопоставление значений из связанных таблиц, разделенных различными строками (например, разделительными запятыми)
- подсказки
- заполнение пустых значений с помощью "None"
- преобразование таймдельта в дни или недели ...
В ряде манипуляций используются simple_tags и фильтры, написанные на python. Есть даже один шаблон, который использует javascript, чтобы сделать некоторые пользовательские вещи с некоторыми colspans, используя события таблицы bootstrap (например, $("#advsrchres").bootstrapTable({onAll: ...).
В каждом примере, на который я смотрю, использующем серверную пагинацию bootstrap-table, нет шаблона, а все данные получены с помощью "data-url", который возвращает JSON.
Надеюсь, что я ошибаюсь, но, по моим представлениям, мне придется переписать все эти украшения ячеек в шаблоне на javascript или что-то в этом роде. Я еще не начал искать, как это сделать, поэтому после долгих бесплодных гуглений я здесь, чтобы узнать, знает ли кто-нибудь способ не переписывать полностью эти огромные шаблоны django, чтобы реализовать пагинацию на стороне сервера? Есть ли способ сказать bootstrap-table вставить данные из JSON в шаблон django?
Вот пример одного из шаблонов...
Здесь следует отметить несколько моментов.
- Я не указал (потому что мне не пришло в голову, что это может иметь значение), что данные, которые я отображаю, являются результатом поиска. Серверная пагинация Bootstrap-table поддерживает только статические данные, поэтому выяснение того, как использовать шаблон, является спорным.
- Хотя вы не можете использовать встроенную функцию пагинации на стороне сервера в bootstrap-table, он предоставляет различные элементы управления пагинацией, так что когда вы реализуете свою собственную пагинацию на стороне сервера, она, по крайней мере, будет использовать преимущества CSS BST.
- Встроенные средства пагинации в Django предназначены только для отдельных моделей и не могут быть применены к поиску, результаты которого не приравниваются к 1 записи = 1 строке.
В итоге я реализовал свой собственный класс пагинатора и воспользовался преимуществами декораций управления пагинатором в BST. Я не буду вдаваться в подробности реализации, поскольку существует множество вариантов, но для того, чтобы развернуть свой собственный пагинатор, когда у вас есть:
- Таблицы, полученные в результате поиска
- Строки ≠ записи (т.е. они не 1:1)
- Соединенные записи
По сути, это то, что вам понадобится:
- Для поиска
- Скрытое поле формы, определяющее параметры поиска (я использовал JSONField)
- Любое другое поле для необязательных элементов управления
- Поле формы для строк на странице
- Поле формы для номера страницы для перехода
- И опционально:
- Поле, указывающее поле, по которому следует сортировать
- Поле для указания направления сортировки
А когда вы выполняете поиск с помощью Django ORM, вы просто нарезаете результаты на основе номера страницы и строк/записей на странице.
В связи с этим следует отметить несколько особенностей Django:
Хотя вы можете использовать .distinct(fields) (с .order_by(field)) для имитации настоящего левого соединения SQL (где вы можете получить дубликаты записей "корневой таблицы"), вы должны иметь дело с несколькими ограничениями:
- Если вы хотите вычислить количество уникальных значений в столбце для получения статистики, вы не можете использовать
.annotate(Count(...)), потому что в итоге возникнет исключениеNotImplemented. - В коде представления у вас есть доступ к "истинному левому соединению" через отношения
M:M, а в шаблоне - нет, и вам придется перебирать все возможные связанные записи для каждой дублирующейся записи корневой таблицы (например,{% for rootTable.MMrecs.all }). Но вы можете обойти это ограничение, используя.annotate()в представлении, например:.annotate("myMMtablerec"=F("MMrecs__pk")). Затем в шаблоне я просто использовал тег шаблона для получения конкретной записи изrootTable.MMrecs.all, принадлежащей этой строке.