@rikkitikki122

Как выйти из вложенного хендлера в aiogram3 python?

Есть хендлер который реагирует на команды "Начать игру" или "Следующий вопрос", при его срабатывании активируется вложенный хендлер который принимает ответ на вопрос переданный при помощи кнопок клавиатуры "answer_btn".
После один из ответов, (который получает вложенный хендлер) обрабатывается функцией check() которая возвращает True/False.
При любом значении result загружается сообщение с подключаемой клавиатурой next_question_keyboard, которая по идее должна отправлять меня к основному хендлеру (на первую строку), но я зависаю во вложенном хендлере.
ps
Код упрощенный для простоты понятия вопроса.

@disp.message(ai.F.text == 'Начать игру' or ai.F.text == 'Следующий вопрос') # основной хендлер
async def start_game(message):
    await message(f'Зимой и летом одним цветом?')
    await message.answer('Варианты ответа: \n a)Ясень  \n b)Ёлка  \n c)Кедр',  reply_markup = answer_btn) # клавиатура с кнопками ответов 
    @disp.message(ai.F.text) # вложенный хендлер
    async def check_answer(message):
        result = check(message.text)
        if result:
            await message.answer('Верно!', reply_markup = next_question_keyboard) # клавиатура с кнопкой "Следующий вопрос"             
        else:
            await message.answer(f'Неверно!', reply_markup = next_question_keyboard) # клавиатура с кнопкой "Следующий вопрос"
  • Вопрос задан
  • 162 просмотра
Пригласить эксперта
Ответы на вопрос 3
@seratkac
Не видел раньше вложенных хендлеров.
Наспех вышел рабочий вариант
код
def check(msg):
    return True


@disp.message(or_f(F.text == 'Начать игру', F.text == 'Следующий вопрос'))  # основной хендлер
async def start_game(message: types.Message):
    await message.answer(f'Зимой и летом одним цветом?')
    await message.answer('Варианты ответа: \n a)Ясень  \n b)Ёлка  \n c)Кедр',
                         reply_markup=answer_btn)  # клавиатура с кнопками ответов


@disp.callback_query(F.data.in_({"a", "b", "c"}))  # вложенный хендлер
async def check_answer(callback: types.CallbackQuery):
    result = check(callback.data)
    answer_text = "Верно!" if result else "Неверно!"
    await callback.message.answer(answer_text,
                                  reply_markup=next_question_btn)  # клавиатура с кнопкой "Следующий вопрос"

spoiler
65cf2adae58d9288317908.png
Ответ написан
@rikkitikki122 Автор вопроса
Понимаю что решение ужасно, но всё же попробовал добавить условие во вложенном хендлере

@disp.message(ai.F.text == 'Начать игру' or ai.F.text == 'Следующий вопрос') # основной хендлер
async def start_game(message):
    await message(f'Зимой и летом одним цветом?')
    await message.answer('Варианты ответа: \n a)Ясень  \n b)Ёлка  \n c)Кедр',  reply_markup = answer_btn) # клавиатура с кнопками ответов 
    @disp.message(ai.F.text) # вложенный хендлер
    async def check_answer(message):
        if message.text == 'Следующий вопрос':
            await start_game(message)
        else:
            result = check(message.text)
            if result:
                await message.answer('Верно!', reply_markup = next_question_keyboard) # клавиатура с кнопкой "Следующий вопрос"             
            else:
                await message.answer(f'Неверно!', reply_markup = next_question_keyboard) # клавиатура с кнопкой "Следующий вопрос"
Ответ написан
@twistfire92
Python backend developer
вы не разобрались с библиотекой. Вот эта вся т.н. вложенность в коде никакой вложенностью в логике не является. Вы должны все хендлеры регистрировать на одном уровне, а не внутри других.

А для реализации вашей логики необходимо использовать машину состояний (FSM)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы