Пагинация в aiogram 3
В этом посте покажу пример создания кнопок пагинации в aiogram 3.
Все статьи
- 13 Сентябрь 2024 Telegram Stars: Подробная инструкция по выводу Комментарии к посту
- 03 Сентябрь 2024 Tortoise ORM - Простая асинхронная альтернатива SQLAlchemy Комментарии к посту
- 26 Август 2024 Пагинация в aiogram 3 Комментарии к посту
- 26 Август 2024 Библиотека Nodriver Комментарии к посту
- 26 Август 2024 Библиотека itsdangerous Комментарии к посту
- 26 Август 2024 Перевод голоса в текст используя Deepgram Комментарии к посту
- 25 Август 2024 Применение Pydantic-моделей к API-ответам Комментарии к посту
- 25 Август 2024 Chocolatey - пакетный менеджер для Windows. Комментарии к посту
- 25 Август 2024 Полезные горячие клавиши в PyCharm Комментарии к посту
Реклама
Меню в Telegram-ботах является важной частью взаимодействия с пользователем. Но, что делать, когда элементов меню много и выводить их "портянкой" из кнопок не совсем удобно? На помощь приходит привычная нам пагинация - переключение страниц, а в случае с ботом, набора кнопок.
Представим, что у нас есть некая функция, возвращающая список товаров. В этом списке 20 элементов, а мы хотим выводить по пять штук. Получается, нам нужно четыре страницы.
Сперва создадим коллбэк-класс Pagination
:
class Pagination(CallbackData, prefix="pag"):
page: int
В этом классе прописываем поле page
- номер страницы.
Затем создаём клавиатуру, выводящую пять элементов из списка. Также в зависимости от того какая сейчас страница две кнопки:
- Если первая, то добавляем только кнопку вперёд.
- Если не первая и не последняя, то две кнопки вперёд и назад.
- Если последняя, то только кнопку назад.
async def get_paginated_kb(page: int = 0) -> InlineKeyboardMarkup:
builder = InlineKeyboardBuilder()
products = await get_products()
start_offset = page * 5
end_offset = start_offset + 5
for product in products[start_offset:end_offset]:
builder.row(InlineKeyboardButton(text=product.title, callback_data=ProductData(id=product.id).pack()))
buttons_row = []
if page > 0:
buttons_row.append(
InlineKeyboardButton(
text="⬅️",
callback_data=Pagination(page=page - 1).pack(),
)
)
if end_offset < len_list:
buttons_row.append(
InlineKeyboardButton(
text="➡️",
callback_data=Pagination(page=page + 1).pack(),
)
)
builder.row(*buttons_row)
return builder.as_markup()
В коде выше мы задали начальное смещение start_offset
и конечное end_offset
, благодаря им, будем получать из списка только нужные элементы.
Затем создаём два простых обработчика.
Первый срабатывает при выполнении команды /products
и выводит сообщение с кнопками товаров.
Второй будет реагировать на нажатия кнопок пагинации и изменять исходное сообщение, выдавая другие товары.
@products_router.message(Command(commands=["products"]))
async def send_products_handler(message: Message):
await message.answer(
text="Список товаров:",
reply_markup=await get_paginated_kb(),
)
@products_router.callback_query(Pagination.filter())
async def products_pagination_callback(callback: CallbackQuery, data: Pagination):
page = data.page
await callback.message.edit_reply_markup(
reply_markup=await get_paginated_kb(page=page)
)
Таким образом в боте можно будет переключаться между страницами с товаром. И конечно же напомню, что это всего лишь пример и реализация в вашем проекте может отличаться.
Arduinum628
2 октября 2024 г. 17:58
len_list - содержимого переменной нет. len(products) нужен
Войдите чтобы добавить комментарий.