如何设置Odoo树视图默认不显示记录仅搜索后展示?
当然有可行的实现方法啦!我整理了几种不同层级的方案,你可以根据自己的Odoo版本和需求来挑选:
方案一:视图动态Domain + 上下文控制(最简单易实现)
这个方案不需要复杂的后端修改,主要通过视图配置和少量前端JS来实现:
- 修改树视图XML:给视图的
domain设置一个依赖上下文的动态表达式,默认返回无结果的条件,有搜索时切换为正常条件:
<tree string="你的视图名称" domain="[('id', '!=', 0) if context.get('has_search', False) else ('id', '=', 0)]"> <!-- 这里是你的字段定义,保持原有内容即可 --> </tree>
- 添加前端搜索监听:继承Odoo的列表控制器,监听搜索和重置搜索事件,更新上下文标志:
odoo.define('your_module.tree_search_trigger', function(require) { "use strict"; var ListController = require('web.ListController'); ListController.include({ _onSearch: function() { // 先执行原生搜索逻辑 this._super.apply(this, arguments); // 添加搜索标志到上下文 this.updateContext({has_search: true}); }, _onResetSearch: function() { // 执行原生重置逻辑 this._super.apply(this, arguments); // 移除搜索标志,回到默认无结果状态 this.updateContext({has_search: false}); } }); });
- 加载JS文件:在模块的
__manifest__.py中把这个JS文件加入assets列表,确保它能被系统加载。
默认打开页面时,上下文没有has_search标志,视图会用id=0的domain(永远无结果);用户搜索后,上下文被更新,domain切换为id!=0(配合搜索条件返回匹配记录);重置搜索后又回到无记录状态。
方案二:后端模型层面控制(更灵活)
如果需要更复杂的判断逻辑(比如区分用户搜索和系统默认加载),可以在模型层面重写搜索方法:
- 继承目标模型:在自定义模块的Python文件中重写
search方法:
from odoo import models, api class YourTargetModel(models.Model): _inherit = 'your.target.model' # 替换成你的模型名称 @api.model def search(self, args, offset=0, limit=None, order=None, count=False): # 判断是否有搜索行为:上下文有标志 或者 搜索参数args非空(排除默认空搜索) if not self.env.context.get('has_search') and not args: # 无搜索时返回空结果 return self.browse() # 有搜索时执行原生搜索逻辑 return super(YourTargetModel, self).search(args, offset=offset, limit=limit, order=order, count=count)
- 前端监听逻辑:和方案一的JS代码一致,搜索时给上下文添加
has_search=True,重置时移除。
这个方案的优势是可以在后端做更精细的逻辑判断,比如结合用户权限、其他上下文参数来控制结果展示。
方案三:纯前端控制(无需后端修改)
如果不想改动后端代码,也可以完全通过前端JS强制控制视图加载:
odoo.define('your_module.tree_hide_default', function(require) { "use strict"; var ListController = require('web.ListController'); ListController.include({ init: function(parent, model, renderer, params) { this._super.apply(this, arguments); // 保存原始默认domain this.originalDomain = params.domain || []; // 初始化时强制设置无结果的domain params.domain = [('id', '=', 0)]; }, _onSearch: function() { // 恢复原始domain再执行搜索 this.model.setDomain(this.originalDomain); this._super.apply(this, arguments); }, _onResetSearch: function() { // 重置回无结果domain this.model.setDomain([('id', '=', 0)]); this._super.apply(this, arguments); } }); });
这个方法直接在视图初始化阶段替换domain为无结果条件,搜索时恢复原始domain,重置时再次替换,全程在前端完成控制。
注意事项
- 以上方案适配Odoo 12及以上版本,不同版本的前端模块路径可能略有差异(比如Odoo 16+核心逻辑兼容,但个别类名可能调整),测试时可以根据实际版本微调。
- 如果你的视图配置了默认搜索过滤器(
search_default_*),需要调整判断逻辑,避免默认过滤器被误屏蔽。 - 测试时别忘了验证高级搜索的场景,确保高级搜索触发时也能正常展示结果。
内容的提问来源于stack exchange,提问作者kholioeg
相关产品推荐
相关产品推荐

