Odoo 10中密码过期登录通知:模板未接收控制器数据排查
Odoo登录模板无法获取控制器传递的密码过期数据问题解决
针对你遇到的模板无法获取控制器传递的days_left数据问题,主要出在控制器逻辑错误、模板继承写法错误以及模型中的一些潜在问题,以下是具体修复方案:
1. 修复控制器逻辑:继承原登录控制器而非重写路由
原控制器直接自定义渲染模板,会丢失原登录页面的上下文数据(如CSRF令牌、错误提示等),正确做法是继承Odoo原生的登录控制器,在其基础上添加自定义参数:
# controllers/main.py from odoo import http from odoo.addons.web.controllers.main import Login class MyLoginController(Login): @http.route() def web_login(self, **kw): # 先调用父类方法,获取原生登录页面的上下文 response = super().web_login(**kw) # 仅当用户输入了登录账号时,查询用户的密码过期状态 days_left = None login = kw.get('login') if login: user = http.request.env['res.users'].sudo().search([('login', '=', login)], limit=1) days_left = user.days_left if user else None # 将days_left注入模板上下文 response.qcontext['days_left'] = days_left return response
2. 修复模板继承:移除错误的t-call标签
原模板中使用t-call="web.login_layout"会覆盖原登录页面的内容,导致自定义的xpath无法正确插入到原生登录表单中,修改后的模板如下:
<!-- views/templates.xml --> <odoo> <template id="login_template" inherit_id="web.login" name="Expired Password Message"> <xpath expr="//div[@class='field-password']" position="after"> <t t-if="days_left == -1"> <div class="alert alert-danger">您的密码已过期,请立即修改。</div> </t> </xpath> </template> </odoo>
3. 优化模型计算逻辑:避免datetime解析错误与时区问题
原模型中手动解析password_write_date存在格式风险,且未处理时区差异,优化后的代码:
# models/password.py from odoo import models, fields, api import datetime class ResUsers(models.Model): _inherit = 'res.users' days_left = fields.Integer(compute='_compute_days_left', string='剩余天数') @api.depends('company_id.password_expiration', 'password_write_date') def _compute_days_left(self): for user in self: # 同时判断密码过期配置和密码修改时间是否存在 if user.company_id.password_expiration and user.password_write_date: # 直接使用Odoo原生的datetime对象,无需手动解析 password_updated_on = user.password_write_date expiration_date = password_updated_on + datetime.timedelta(days=user.company_id.password_expiration) # 使用UTC时间比较,避免时区不一致问题 today = datetime.datetime.now(datetime.timezone.utc) if today > expiration_date: user.days_left = -1 else: user.days_left = (expiration_date - today).days else: user.days_left = -1 def __init__(self, pool, cr): super(ResUsers, self).__init__(pool, cr) type(self).SELF_WRITEABLE_FIELDS = list(self.SELF_WRITEABLE_FIELDS) + ['days_left']
关键问题总结
- 控制器必须继承原生登录逻辑,否则会丢失模板上下文的核心数据
- 模板继承时不要随意使用
t-call覆盖原模板结构,应通过xpath精准插入内容 - 处理datetime字段时优先使用Odoo原生对象,避免手动解析带来的格式错误
- 必须处理用户不存在、字段为空等边界情况,避免报错
内容的提问来源于stack exchange,提问作者lostinspace
相关产品推荐
相关产品推荐

