Odoo 10实现记录不存在时展示404页面的技术问询
在Odoo 10中实现自定义404页面(记录删除时触发)
我刚好在Odoo 10里处理过几乎一模一样的需求——邮件里的记录链接被删除后,用户访问时直接显示友好的404页面,而不是Odoo默认的生硬错误提示。下面分享两个亲测有效的方案,你可以根据自己的场景选择:
方案一:针对特定模型/路由定制(推荐,更灵活)
这个方案适合你只需要处理某几个特定模型链接的场景,比如你邮件里发送的客户订单、项目记录等。
步骤1:创建自定义模块
新建一个名为website_custom_404的模块,在__manifest__.py里声明依赖website和web模块。
步骤2:编写控制器捕获错误
在模块的controllers目录下创建main.py,代码如下:
from odoo import http from odoo.http import request from odoo.exceptions import MissingError, AccessError class Custom404Controller(http.Controller): # 示例:处理你邮件中发送的特定模型链接,比如销售订单 @http.route(['/sale/order/<int:order_id>'], type='http', auth="public", website=True) def sale_order_page(self, order_id, **kw): # 尝试获取记录,公共访问场景下适当提升权限 order = request.env['sale.order'].sudo().browse(order_id) # 判断记录是否存在 if not order.exists(): # 渲染自定义404页面 return request.render('website_custom_404.custom_404_page') # 记录存在时,继续原有的页面渲染逻辑 return request.render('sale.sale_order_portal_template', {'order': order}) # 可选:处理附件等静态资源的404 @http.route('/web/content/<model("ir.attachment"):attachment>', type='http', auth="public") def content(self, attachment, **kw): try: return super(Custom404Controller, self).content(attachment, **kw) except (MissingError, AccessError): return request.render('website_custom_404.custom_404_page')
步骤3:创建404页面模板
在views目录下创建404_template.xml:
<odoo> <template id="custom_404_page" inherit_id="website.layout"> <xpath expr="//div[@id='wrap']" position="replace"> <div id="wrap" class="oe_empty"> <div class="container text-center mt-5"> <h1 class="display-1 text-danger">404</h1> <h3>页面不存在</h3> <p class="lead">你访问的记录已被删除,或者该页面从未存在过。</p> <a href="/" class="btn btn-primary mt-3">返回首页</a> </div> </div> </xpath> </template> </odoo>
方案二:全局捕获记录不存在错误
如果你希望所有因记录删除/权限不足导致的错误都跳转到404页面,可以用这个全局方案:
编写继承控制器
在controllers/main.py中添加:
from odoo.addons.web.controllers.main import Home from odoo.exceptions import MissingError, AccessError from odoo.http import request class GlobalErrorHandler(Home): @http.route() def web_client(self, s_action=None, **kw): try: return super(GlobalErrorHandler, self).web_client(s_action, **kw) except (MissingError, AccessError) as e: # 只在网站前端访问时跳404,后台保留原错误提示 if request.website: return request.render('website_custom_404.custom_404_page') # 后台访问时抛出原错误 raise
注意事项
- 替换代码中的
sale.order和对应路由为你实际使用的模型和链接格式 - 模块安装后记得升级模块,并清除浏览器缓存测试
- 如果需要区分“记录不存在”和“无权限访问”,可以在捕获
AccessError时添加额外判断(比如先检查记录是否真的存在)
我当时用的是方案一,因为只需要处理几个特定业务模型的链接,灵活性更高。如果你的需求是全局覆盖所有场景,方案二更省心~
内容的提问来源于stack exchange,提问作者Ancient
相关产品推荐
相关产品推荐

