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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 11:40:25