如何从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
相关产品推荐
相关产品推荐

