Odoo16中如何修改表单视图内Tree组件的属性?
问题分析与解决方法
你遇到的核心问题是get_view方法的定位不对:它是模型级方法(被@api.model装饰),执行时self是空的记录集,依赖context里的active_id不可靠——比如视图预加载、批量操作场景下,active_id不一定是当前打开的表单记录ID。
正确的做法是使用fields_view_get方法,这个方法在加载单个记录表单视图时会被触发,且此时self就是当前打开的记录实例,能直接获取到该记录的属性值。
修正后的代码实现
from odoo import models, fields, api from lxml import etree import logging class StockPicking(models.Model): _inherit = "stock.picking" limit = fields.Integer(string="Tree Pagination Limit") def tree_pagination_limit_apply(self): return { 'type': 'ir.actions.client', 'tag': 'reload', } @api.multi def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False): logging.info("Custom fields_view_get called") # 先获取原始视图架构 result = super(StockPicking, self).fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu) if view_type == 'form' and self: # 仅处理表单视图,且当前有打开的记录 doc = etree.XML(result['arch']) # 定位表单内的目标tree组件 for tree in doc.xpath("//field[@name='move_ids_without_package']/tree"): # 直接用当前记录的limit值,无需依赖context current_limit = self.limit if current_limit > 0: tree.set('limit', str(current_limit)) logging.info(f"Set tree view limit to {current_limit}") else: # 如果limit为0或空,移除limit属性(恢复默认) if tree.get('limit'): tree.attrib.pop('limit') # 更新视图架构 result['arch'] = etree.tostring(doc, encoding='unicode') return result
关键说明
- 方法选择:
fields_view_get是记录集级方法(@api.multi装饰),打开单个表单时self就是该记录,直接读取self.limit即可,完全避免了active_id的不可靠问题。 - 视图修改逻辑:找到目标tree组件后,根据当前记录的
limit值设置属性;如果limit为0或未设置,移除limit属性恢复系统默认分页。 - 生效时机:每次打开表单视图、点击
tree_pagination_limit_apply触发页面重载时,该方法都会执行,确保tree组件的limit属性与当前记录的设置同步。
内容的提问来源于stack exchange,提问作者Neural
相关产品推荐
相关产品推荐

