Как реализовать кнопку подгрузки дополнительных статей. На Django, REST API, HTMx и daisyUI
01.04.2025
15.04.2025
6 минут
53
0
0
0
0
Вступление
В этой статье я покажу как можно реализовать подгрузку дополнительного контента, аля страниц пагинации. С использованием django, rest_API, htmx и daisyUI. Так же я исхожу из мысли, что ты, мой дорогой уже создал виртуальное окружение для django-проекта, установил и настроил rest-api и в целом имеешь проект готовый для разработки. В этой статье настроек и предустановок не будет, сразу перейдём к сути. Демонстрировать всё я буду на своём новом сайте, про историю.
Пишем фронтенд
Для начала, нам потребуется страница для размещения кнопки загрузки контента и шаблоны для отрисовки загружаемого контента. Например, у меня есть домашняя страница, мне нужно вставить подключить следующий шаблон.
Не так важно во что ты обернёшь подключаемый шаблон. Я вот, собираюсь подгружать статьи и хочу чтобы они все были в столбик, но не слишком широкий. Важно то, что нужно передать переменную articles в подключаемый шаблон parts/article-simple-paginator.html. Откуда её взять, переменную смотри в следующей главе, сейчас разберём другие составляющие наших шаблонов.
Исходный код parts/article-simple-paginator.html:
Данный сниппет кода представляет собой флекс-бокс в колонку, для карточек статей и собственно кнопки загрузки в самом конце. Когда мы подключаем шаблон для отрисовки карточек статей, мы так же не забываем отправить туда articles переменную.
После (выделено жёлтым) идёт логика отображения кнопки подгрузки контента. Если is_not_init равно false, то есть, если это мой первый визит страницы, то при помощи django-тега with я вручную собираю ссылку которую потом, будет использовать кнопка для отправки запроса на сервер.
Но если, это всё-таки не первый визит и is_not_init равно true, то использя rest_api пагинатор, я получаю и отравляю ссылку на следующую страницу. И если, переменная next не определена, то есть мы в конце и больше нечего загружать, мы не отрисовываем данную кнопку.
Теперь, собственно говоря, про саму кнопку загрузки, шаблон parts/more-button.html:
Пройдёмся по атрибутам, в порядке нисходящем).
- id - обычный АйДи кнопки, потребуется для того чтобы после можно было её найти
- class - используя классы от daisyUI, стилизуем кнопку
- hx-get - куда отправляем запрос
- hx-target - куда вставляем ответ от сервера
- hx-indicator - индикатор для отображения пока грузится контент
- hx-swap - как вставляем контент, относительно hx-target. outerHTML значит вставить загруженный контент в родительский элемент дерева DOM, с сохранением самой кнопки.
Класс .htmx-indicator - это указатель со стилями по умолчанию. Собственно, указываем, что это наш индикатор.
Можно ещё рассмотреть шаблон parts/article-cards.html, но в этом не очень много смысла, ибо он уже зависит от того что конкретно, ты хочешь отобразить. В моём случае это статьи, но в твоём это может быть что угодно. Но в любом случае, это обязательно должна быть коллекция чего-то. И вот код:
И вот, так это выглядит на самом сайте:

Я ещё не совсем полностью стилизовал сайт, но уже не плохо, я думаю
Пишем бэкенд
Теперь про бэкенд. Начнём с того, что напишем класс-представление для той страницы, где надо подгружать статьи. В файле, Frontend/views.py:
В общем и целом, идея такова: нужно вернуть коллекцию статей и номер страницы пагинации при GET запросе. Вообще, это всё не обязательно писать, если тебе не надо контент при первом запросе, то есть ты не против пустой страницы изначально.
Здесь всё, хотя ещё надо заметить, как и сколько элементов я возвращаю. Фильтрую я их по языку (не обязательно если одноязычный сайт). Сортирую по дате публикации(сначала идут самые новые). И наконец, возвращаю ровно столько, сколько определено в пагинаторе StandartPagination.
Теперь напишем сереализатор той модели, которую нужно будет подгружать. Это для работы с REST API. И, так как у меня это статьи, выглядит этот сереализатор вот так, в файле Backend/serializers.py:
Да, столько вот у меня полей для статьи, много ...
С готовым серелиазатором и моделью для подгрузки, можно написать ещё один класс-представление, специально для подгрузки при нажатии кнопки "Ещё":
Здесь, мы создаём пагинатор, унаследовавшись от класса PageNumberPaginator от REST API. Где указываем количество элементов на страницу(page_size) и всего доступных элементов(max_page_size).
Непосредственно загрузкой необходимых статей будет заниматься класс ArticlePaginatedModelView, которую мы сделаем, унаследовавшись от миксина ListAPIView. Специальный класс от REST API, который создан, чтобы проходить по большим коллекциям элементов.
Правда, его нужно предварительно настроить, чтобы он заработал корректно:
- serializer_class - Указываем серелиазатор, который будет испльзоваться для получения сырых данных о модели
- renderer_classes - то как будем возвращать результат, если не указывать будет возвращать JSON файл, нам нужен отрендереный кусок HTML, по этому используем TemplateHTMLRenderer
- template_name - в какой шаблон будет отрисовываться коллекция подгружаемых элементов
- pagination_class - как будем проходить по коллекции элементов
- queryset - какие элементы будем подгружать
И чтобы вернуть, конкретно коллекцию, необходимо переопределить метод list. Где мы фильтруем нашу коллекцию по языку(необязательно). Можно просто get_queryset().
Дальше, получаем срез необходимых элементов для подгрузки и ссылку на следующую страницу, если таковая будет (элементы закончились). И чтобы обозначить, что данный запрос это не первый, определяем тут переменную is_not_init = True.
Всё готово, осталось только подключить данные представления в Backend/urls.py:
Заключение
Данного кода должно хватить, чтобы написать обычную кнопку подгрузки контента с сервера, используя только Django как основу, немного REST API и ещё меньше HTMx.
Комментарии
(0)
Отправить
Сейчас тут пусто. Буть первым (o゚v゚)ノ