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

如何从MongoDB取出的角色列表为用户添加多个角色?解决AttributeError

解决AttributeError: 'str' object has no attribute 'id'问题

问题根源

你在存储角色时,用str(r)把Discord的Role对象转换成了字符串,从数据库取出后得到的是字符串列表,而author.add_roles()方法需要传入实际的Role对象,不是字符串,因此触发了属性错误。

修复方案

1. 修改角色存储逻辑:存储角色ID而非字符串

角色ID是唯一不变的标识,比字符串更适合持久化存储,也方便后续还原为Role对象:

def add_roles_to_db(self):
    check = cursor.find_one({"_id": self.ctx.author.id})
    # 提取角色ID(整数类型)存入数据库
    role_ids = [r.id for r in self.ctx.author.roles[1:]]
    if check is None:
        cursor.insert_one({"_id": self.ctx.author.id, "roles": role_ids})
    else:
        cursor.update_one({"_id": self.ctx.author.id}, {"$set": {"roles": role_ids}})

2. 修改角色获取逻辑:将ID还原为Role对象

从数据库取出ID后,通过服务器上下文获取对应的Role对象,同时过滤掉已被删除的无效角色:

def get_roles_from_db(self):
    data = cursor.find_one({"_id": self.ctx.author.id})
    if not data or "roles" not in data:
        return []
    # 将ID转换为Role对象,过滤不存在的角色
    return [
        self.ctx.guild.get_role(role_id) 
        for role_id in data["roles"] 
        if self.ctx.guild.get_role(role_id) is not None
    ]

3. 正常调用添加角色方法

现在获取到的是有效的Role对象列表,可直接传入add_roles:

roles = self.get_roles_from_db()
if roles:
    await author.add_roles(*roles)

补充说明

之前用str(r)存储的是角色的字符串表示(类似<Role id=123456 name="管理员">),这种字符串无法直接还原为Role对象,而存储角色ID是Discord Bot开发中持久化角色的标准做法,既稳定又易于处理。

内容的提问来源于stack exchange,提问作者Dr. Troll

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:50:33