Odoo如何按模型数据动态渲染表单视图?解决缓存异常
Odoo 表单视图条件渲染及缓存问题解决
一、条件渲染表单视图的实现方式
要根据模型状态等动态切换表单视图,核心是重写模型的get_view方法——该方法负责返回当前请求对应的视图定义,我们可以在方法内根据记录的状态等条件,替换为目标视图的信息。
具体步骤:
- 在Odoo界面创建好4个目标表单视图,记录每个视图的名称或ID;
- 在目标模型的Python代码中重写
get_view方法; - 方法内获取当前访问的记录,根据记录状态等条件判断要切换的视图;
- 替换返回结果中的视图ID、架构(arch)等关键信息。
二、解决重写get_view后的缓存问题
仅刷新页面才生效的问题,根源是Odoo前端会缓存视图数据,切换记录时默认不会重新调用get_view。可以从以下两方面解决:
1. 强制前端切换记录时重新加载视图
重写fields_view_get方法,给视图添加动态缓存键,让前端识别到记录变化时重新请求视图:
def fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False): result = super().fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu) if view_type == 'form' and self.env.context.get('params', {}).get('id'): # 用当前记录ID作为缓存键,确保不同记录触发视图重新加载 result['cache_key'] = str(self.env.context['params']['id']) return result
2. 优化get_view方法的逻辑
你的现有代码存在可优化点,同时要确保视图切换逻辑可靠:
- 避免硬编码视图名称,建议结合模型条件搜索视图,防止匹配到其他模型的同名视图;
- 补充字段信息的正确获取逻辑(原代码中
model_fields和related_model_fields未定义,需通过fields_get()获取); - 增加状态判断逻辑,对应到你创建的4个视图。
优化后的get_view示例:
def get_view(self, view_id=None, view_type='form', **options): result = super().get_view(view_id=view_id, view_type=view_type, **options) if view_type == 'form' and 'params' in self._context and 'id' in self._context['params']: record = self.browse(self._context['params']['id']) # 根据记录state字段匹配对应视图,替换成你的实际状态和视图名称 view_mapping = { 'draft': '草稿状态视图', 'confirmed': '已确认状态视图', 'done': '已完成状态视图', 'cancel': '已取消状态视图', } target_view_name = view_mapping.get(record.state, '默认表单视图') # 搜索目标视图,添加模型条件确保准确性 target_view = self.env['ir.ui.view'].search([ ('name', '=', target_view_name), ('model', '=', self._name) ], limit=1) if target_view: # 获取当前模型及关联模型的字段信息 model_fields = self.fields_get() related_model_fields = self.env['related.model'].fields_get() # 替换为你的关联模型 result.update({ 'id': target_view.id, 'arch': target_view.arch_db, 'model': self._name, 'models': { self._name: model_fields, 'related.model': related_model_fields }, }) return result
3. 额外注意事项
- 确保所有自定义视图已正确关联到目标模型;
- 测试前清除浏览器缓存,避免旧缓存干扰;
- 若涉及权限控制,需在视图切换逻辑中添加用户权限判断,确保用户只能访问有权限的视图。
内容的提问来源于stack exchange,提问作者Riajul Kashem
相关产品推荐
相关产品推荐

