Odoo公开请求控制器创建线索报错:Expected singleton: res.users()
解决Odoo auth='none'控制器创建crm.lead时的res.users非单例异常
问题原因
当控制器设置auth='none'时,Odoo不会为请求绑定登录用户,此时self.env.user是一个空的用户集合(非单例对象)。而crm.lead继承了mail.thread模型,创建线索时会触发邮件线程的默认逻辑,调用message_post方法时会执行self.env.user._is_public()判断,由于self.env.user不是单例,直接抛出ValueError: Expected singleton: res.users()异常。
解决方案
方法1:绑定公开用户创建线索
Odoo默认存在一个公开用户(base.public_user),可以手动将创建线索的环境切换为该用户,确保self.env.user是单例对象:
# 获取系统默认的公开用户 public_user = self.env.ref('base.public_user') # 使用公开用户的环境创建crm.lead lead = self.env['crm.lead'].with_user(public_user).create({ 'name': '客户线索', 'partner_id': partner_id, # 已创建的res.partner ID 'email_from': 'customer@example.com', # 其他必填字段 })
方法2:禁用邮件线程自动消息
如果业务不需要线索创建时自动生成邮件消息,可以通过上下文参数禁用相关逻辑,避免触发message_post:
lead = self.env['crm.lead'].with_context( mail_create_nosubscribe=True, mail_auto_subscribe_no_notify=True ).create({ 'name': '客户线索', 'partner_id': partner_id, 'email_from': 'customer@example.com', # 其他必填字段 })
注意:该方法会跳过线索的订阅通知逻辑,需根据业务需求选择。
方法3:使用专用系统用户认证
如果业务允许,可以创建一个专用的系统用户,将控制器的auth改为user,并在请求中携带该用户的认证信息(如API密钥),让Odoo自动绑定单例用户,从根源避免非单例问题。
内容的提问来源于stack exchange,提问作者hardik device
相关产品推荐
相关产品推荐

