Сделал динамическое добавление инлайн кнопок в тг боте с выгрузкой из БД, но выводит почему-то только последнюю добавленную кнопку

Рейтинг: 0Ответов: 1Опубликовано: 18.04.2023

Доброй ночи, помогите, пожалуйста. Сделал динамическое добавление кнопок с выгрузкой из БД. Кнопки создаются отлично, но есть 2 косяка. 1: Кнопка создаётся только после рестарта бота. 2: Работает callback только последней кнопки, остальные не работают сколько их бы не было

Код создания кнопок:

items = [row[0] for row in db.cur.execute('SELECT model FROM items').fetchall()]
markup = InlineKeyboardMarkup(row_width=2)  # создаём клавиатуру
for model in items:
    markup.add(InlineKeyboardButton(text=model, callback_data=model))

Код callback_query:

@dp.callback_query_handler()
async def callback_query_keyboard_shoes(callback_query: types.CallbackQuery):
    if callback_query.data == model:
        brend2_name = model
        # получение данных из таблицы
        db.cur.execute("SELECT model, price, brang, photo_it FROM items WHERE model = ?",
                       (brend2_name,))
        data = db.cur.fetchall()
        # форматирование данных в виде строки
        text = ''
        for row in data:
            text += f"model: {row[0]}\n price: {row[1]}\nbrend: {row[2]}"
        await bot.send_message(callback_query.from_user.id, text=text)
        await bot.send_photo(callback_query.from_user.id, photo=row[3])

введите сюда описание изображения

Ответы

▲ 0

Предположу, судя по приведенному коду, что у вот эта часть у вас выполняетяс на самом верхнем уровне, не в хендлере:

items = [row[0] for row in db.cur.execute('SELECT model FROM items').fetchall()]
markup = InlineKeyboardMarkup(row_width=2)  # создаём клавиатуру
for model in items:
    markup.add(InlineKeyboardButton(text=model, callback_data=model))

От этого и обе проблемы:

  1. Поскольку этот кусок в "корне", а не в функции хендлере, то и выполняется он только 1 раз при старте бота.
  2. Тут проблема состоит из 2 частей:

а) непонятно зачем нужный if в начале обработчика

@dp.callback_query_handler()
async def callback_query_keyboard_shoes(callback_query: types.CallbackQuery):
    if callback_query.data == model: # <-- вот это для чего?
        brend2_name = model
# ...
# ...

б) если предположение 1 верно, то, по завершении цыкла for model in items:, у вас остается глобальная переменная model, равная последнему элементу из БД. Поэтому шаг с проверкой if callback_query.data == model и пропускает только на последнюю добавленную кнопку.