You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Discord.py中将变量传入Modal的on_submit()方法?

解决Discord Modal自定义__init__传参时的AttributeError问题

错误原因

自定义ModalApplicationForm的__init__方法时,未调用父类discord.ui.Modal的构造函数,导致Modal类必需的核心属性(如custom_id)未被初始化,从而触发AttributeError。

修正方案

在自定义的__init__方法中,必须先调用super().__init__()完成父类初始化,再添加自定义变量。同时可将角色ID等需要传递的参数传入,供on_submit方法使用。

完整修正代码

import discord
from discord.ext import commands
from discord import ui

intents = discord.Intents.default()
intents.members = True
intents.message_content = True

bot = commands.Bot(command_prefix="!", intents=intents)

@bot.event
async def on_ready():
    bot.add_view(ViewAllianceSelection())
    await bot.tree.sync()

# 角色选择视图
class ViewAllianceSelection(discord.ui.View):
    def __init__(self):
        super().__init__(timeout=None)
    
    # 示例三个角色按钮,custom_id替换为实际角色ID
    @discord.ui.button(label="联盟1", custom_id="123456789012345678", style=discord.ButtonStyle.green)
    async def role1_btn(self, interaction: discord.Interaction, button: discord.Button):
        # 将按钮的custom_id(角色ID)传入Modal
        await interaction.response.send_modal(ModalApplicationForm(target_role_id=button.custom_id))
    
    @discord.ui.button(label="联盟2", custom_id="987654321098765432", style=discord.ButtonStyle.blue)
    async def role2_btn(self, interaction: discord.Interaction, button: discord.Button):
        await interaction.response.send_modal(ModalApplicationForm(target_role_id=button.custom_id))
    
    @discord.ui.button(label="联盟3", custom_id="112233445566778899", style=discord.ButtonStyle.red)
    async def role3_btn(self, interaction: discord.Interaction, button: discord.Button):
        await interaction.response.send_modal(ModalApplicationForm(target_role_id=button.custom_id))

# 申请Modal
class ModalApplicationForm(discord.ui.Modal, title='联盟申请表单'):
    def __init__(self, target_role_id):
        # 先调用父类构造函数,初始化Modal必要属性
        super().__init__(title=self.title)
        # 保存自定义变量:目标角色ID
        self.target_role_id = target_role_id
        # 添加文本输入组件
        self.submittedUN = ui.TextInput(label='输入你的用户名', style=discord.TextStyle.short)
        self.add_item(self.submittedUN)
    
    async def on_submit(self, interaction: discord.Interaction):
        # 获取用户输入的用户名
        username = self.submittedUN.value
        # 获取目标角色
        target_role = interaction.guild.get_role(int(self.target_role_id))
        if target_role:
            # 为用户分配角色
            await interaction.user.add_roles(target_role)
            # 存入数据库(替换为你的实际数据库逻辑)
            print(f"已记录申请:用户 {interaction.user.id},用户名 {username},角色 {target_role.name}")
            # 回复用户
            await interaction.response.send_message(f'感谢**{username}**,你的申请已提交,已为你分配{target_role.name}角色!', ephemeral=True)
        else:
            await interaction.response.send_message('错误:无法找到目标角色', ephemeral=True)

@bot.command()
async def send_view(ctx):
    embed = discord.Embed(title='联盟角色申请')
    await ctx.send(embed=embed, view=ViewAllianceSelection())

bot.run('你的机器人Token')

关键要点

  • 必须调用父类构造函数:super().__init__(title=self.title)是核心,确保Modal的custom_id等必要属性被初始化。
  • 自定义变量传递:通过__init__参数传入角色ID,在on_submit中直接使用self.target_role_id即可。
  • 组件添加方式:文本输入组件可放在__init__里用self.add_item()添加,也可保持类属性定义,两种方式均有效。

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 01:03:12