odoo17核心概念view5——ir_ui_view.py

这是view系列的第5篇文章,介绍一下view对应的后端文件ir_ui_view.py,它是base模块下的一个文件
位置:odoo\addons\base\models\ir_ui_view.py

该文件一共定义了三个模型

1.1 ir.ui.view.custom

查询数据库这个表是空的,从名字看和数据库表结构看, 这个表应该是view和user的三方表,可以根据用户自定义view, 但是案例呢?

class ViewCustom(models.Model):_name = 'ir.ui.view.custom'_description = 'Custom View'_order = 'create_date desc'  # search(limit=1) should return the last customization_rec_name = 'user_id'ref_id = fields.Many2one('ir.ui.view', string='Original View', index=True, required=True, ondelete='cascade')user_id = fields.Many2one('res.users', string='User', index=True, required=True, ondelete='cascade')arch = fields.Text(string='View Architecture', required=True)def _auto_init(self):res = super(ViewCustom, self)._auto_init()tools.create_index(self._cr, 'ir_ui_view_custom_user_id_ref_id',self._table, ['user_id', 'ref_id'])return res

1.2 ir.ui.view

截取一部分字段, view的字典表,保存从xml中解析的view信息。


class View(models.Model):_name = 'ir.ui.view'_description = 'View'_order = "priority,name,id"name = fields.Char(string='View Name', required=True)model = fields.Char(index=True)key = fields.Char(index='btree_not_null')priority = fields.Integer(string='Sequence', default=16, required=True)type = fields.Selection([('tree', 'Tree'),('form', 'Form'),('graph', 'Graph'),('pivot', 'Pivot'),('calendar', 'Calendar'),('gantt', 'Gantt'),('kanban', 'Kanban'),('search', 'Search'),('qweb', 'QWeb')], string='View Type')arch = fields.Text(compute='_compute_arch', inverse='_inverse_arch', string='View Architecture',help="""This field should be used when accessing view arch. It will use translation.Note that it will read `arch_db` or `arch_fs` if in dev-xml mode.""")arch_base = fields.Text(compute='_compute_arch_base', inverse='_inverse_arch_base', string='Base View Architecture',help="This field is the same as `arch` field without translations")arch_db = fields.Text(string='Arch Blob', translate=xml_translate,help="This field stores the view arch.")arch_fs = fields.Char(string='Arch Filename', help="""File from where the view originates.Useful to (hard) reset broken views or to read arch from file in dev-xml mode.""")

1.3 Model

这是一个抽象模型,

class Model(models.AbstractModel):_inherit = 'base'_date_name = 'date'         #: field to use for default calendar view

它继承自base模型,让我们看看base模型是何方神圣,从注释看,这是一个基本模型,所有的模型都要继承它。
odoo\addons\base\models\ir_model.py
这是一个抽象模型,抽象的只有一名字而已。估计又很多地方对这个模型进行了扩展。我们搜索一下

#
# IMPORTANT: this must be the first model declared in the module
#
class Base(models.AbstractModel):""" The base model, which is implicitly inherited by all models. """_name = 'base'_description = 'Base'

在这里插入图片描述
前端的viewService中通过orm调用的getViews就是最终就是调用了这个模型的get_views方法

    @api.modeldef get_views(self, views, options=None):""" Returns the fields_views of given views, along with the fields ofthe current model, and optionally its filters for the given action.The return of the method can only depend on the requested view types,access rights (views or other records), view access rules, options,context lang and TYPE_view_ref (other context values cannot be used).Python expressions contained in views or representing domains (onpython fields) will be evaluated by the client with all the contextvalues as well as the record values it has.:param views: list of [view_id, view_type]:param dict options: a dict optional boolean flags, set to enable:``toolbar``includes contextual actions when loading fields_views``load_filters``returns the model's filters``action_id``id of the action to get the filters, otherwise loads the globalfilters or the model:return: dictionary with fields_views, fields and optionally filters"""

调用链条:
get_views => get_view => _get_view_cache => _get_view
重点看一下 _get_view这个私有函数:

 @api.modeldef _get_view(self, view_id=None, view_type='form', **options):"""Get the model view combined architecture (the view along all its inheriting views).:param int view_id: id of the view or None:param str view_type: type of the view to return if view_id is None ('form', 'tree', ...):param dict options: bool options to return additional features:- bool mobile: true if the web client is currently using the responsive mobile view(to use kanban views instead of list views for x2many fields):return: architecture of the view as an etree node, and the browse record of the view used:rtype: tuple:raise AttributeError:if no view exists for that model, and no method `_get_default_[view_type]_view` exists for the view type"""View = self.env['ir.ui.view'].sudo()# try to find a view_id if none providedif not view_id:# <view_type>_view_ref in context can be used to override the default viewview_ref_key = view_type + '_view_ref'view_ref = self._context.get(view_ref_key)if view_ref:if '.' in view_ref:module, view_ref = view_ref.split('.', 1)query = "SELECT res_id FROM ir_model_data WHERE model='ir.ui.view' AND module=%s AND name=%s"self._cr.execute(query, (module, view_ref))view_ref_res = self._cr.fetchone()if view_ref_res:view_id = view_ref_res[0]else:_logger.warning('%r requires a fully-qualified external id (got: %r for model %s). ''Please use the complete `module.view_id` form instead.', view_ref_key, view_ref,self._name)if not view_id:# otherwise try to find the lowest priority matching ir.ui.viewview_id = View.default_view(self._name, view_type)if view_id:# read the view with inherited views appliedview = View.browse(view_id)arch = view._get_combined_arch()else:# fallback on default views methods if no ir.ui.view could be foundview = View.browse()try:arch = getattr(self, '_get_default_%s_view' % view_type)()except AttributeError:raise UserError(_("No default view of type '%s' could be found!", view_type))return arch, view

如果没有传入view_id, 那么就去上下文中查找_view_ref, 这给了我们一种思路,那就是可以在上下文中指定视图。
如果还是获取不到view_id,那么调用View.default_view函数获取默认的视图。
如果获取到了view_id, view返回该条记录,而arch返回处理好继承关系之后的结构

            view = View.browse(view_id)arch = view._get_combined_arch()

如果view_id 还是没有获取到,那么还是做了最后的尝试

arch = getattr(self, '_get_default_%s_view' % view_type)()

调用了视图类型对应的函数,以form为例,调用_get_default_form_view返回arch,如果没有这个函数,那就抛出异常。 odoo: 我已经尽了我最大的努力了。。。

1.4 view_ref 应用的案例

<page string="Analytic Lines" name="analytic_lines" groups="analytic.group_analytic_accounting"><field name="date" invisible="1"/><field name="analytic_line_ids" context="{'tree_view_ref':'analytic.view_account_analytic_line_tree', 'default_general_account_id':account_id, 'default_name': name, 'default_date':date, 'amount': (debit or 0.0)-(credit or 0.0)}"/>
</page>

随便找了 一个例子,这是一个x2many字段,在context中指定了 tree_view_ref,那么系统在打开的时候就会调用这里指定的tree视图,而不是默认的tree视图。

ir_ui_view.py的代码有3000行,这里只介绍了很少的一部分,后面如果有其他的知识点,再来补充。

1.5 _get_default_form_view

通过代码动态生成视图,这给了我们一共思路,就是在审批流中等需要动态生成视图的场景下,可以参考这种方式。
本质是动态生成或者改变arch,在后端或者前端都可以做。

@api.modeldef _get_default_form_view(self):""" Generates a default single-line form view using all fieldsof the current model.:returns: a form view as an lxml document:rtype: etree._Element"""sheet = E.sheet(string=self._description)main_group = E.group()left_group = E.group()right_group = E.group()for fname, field in self._fields.items():if field.automatic:continueelif field.type in ('one2many', 'many2many', 'text', 'html'):# append to sheet left and right group if neededif len(left_group) > 0:main_group.append(left_group)left_group = E.group()if len(right_group) > 0:main_group.append(right_group)right_group = E.group()if len(main_group) > 0:sheet.append(main_group)main_group = E.group()# add an oneline group for field type 'one2many', 'many2many', 'text', 'html'sheet.append(E.group(E.field(name=fname)))else:if len(left_group) > len(right_group):right_group.append(E.field(name=fname))else:left_group.append(E.field(name=fname))if len(left_group) > 0:main_group.append(left_group)if len(right_group) > 0:main_group.append(right_group)sheet.append(main_group)sheet.append(E.group(E.separator()))return E.form(sheet)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/300624.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32独立看门狗

时钟频率 40KHZ 看门狗简介 STM32F10xxx 内置两个看门狗&#xff0c;提供了更高的安全性、时间的精确性和使用的灵活性。两个看 门狗设备 ( 独立看门狗和窗口看门狗 ) 可用来检测和解决由软件错误引起的故障&#xff1b;当计数器达到给 定的超时值时&#xff0c;触发一个中…

HarmonyOS共享包HAR

共享包概述 OpenHarmony提供了两种共享包&#xff0c;HAR&#xff08;Harmony Archive&#xff09;静态共享包&#xff0c;和HSP&#xff08;Harmony Shared Package&#xff09;动态共享包。 HAR与HSP都是为了实现代码和资源的共享&#xff0c;都可以包含代码、C库、资源和配…

基于java+控件台+mysql的学生信息管理系统(含演示视频)

基于java控件台mysql的学生信息管理系统_含演示视频 一、系统介绍二、功能展示1.项目内容2.项目骨架3.数据库4.登录系统5.新增学生6.查询学生7.修改学生8.删除学生9.退出系统 四、其它1.其他系统实现五.获取源码 一、系统介绍 项目类型&#xff1a;Java SE项目&#xff08;控制…

云计算、大数据、人工智能、物联网、虚拟现实技术、区块链技术(新一代信息技术)学习这一篇够了!

目录 云计算 一、云计算的基本概念 二、云计算的分类 (一) IaaS (二) SaaS (三) PaaS 三、云环境的分类、云计算的四种部署模式 (一)公有云 (二)私有云 (三)社区云 (四)混合云 四、云计算的特点 (一)虚拟化技术 (二)动态可扩展 (三)按需部署 (四)灵活性高 (五…

算法leetcode|94. 二叉树的中序遍历(多语言实现)

文章目录 94. 二叉树的中序遍历&#xff1a;样例 1&#xff1a;样例 2&#xff1a;样例 3&#xff1a;提示&#xff1a; 分析&#xff1a;题解&#xff1a;rust&#xff1a;go&#xff1a;c&#xff1a;python&#xff1a;java&#xff1a; 94. 二叉树的中序遍历&#xff1a; …

OpenCV-Python(14):图像几何变换

背景说明 图像几何变换是计算机视觉和图像处理领域中的重要技术。它通过对图像进行平移、旋转、缩放、翻转等操作&#xff0c;改变图像的大小、位置或方向&#xff0c;以实现对图像的变换和处理。 图像几何变换在很多应用中都有广泛的应用&#xff0c;例如&#xff1a; 视觉定…

【安全学习】-网络安全靶场实训演练系统建设方案

目 录 第1章需求分析 1.1建设需求 1.2建设目标与内容 第2章系统整体建设 2.1设计思想 2.2建设目标 2.3架构设计 2.4系统设计 2.4.1基础平台系统设计 2.4.2实训分系统设计 2.4.3考核分系统设计 2.4.4拓扑设计分系统设计 2.4.5模拟仿真系统设计 2.4.5.1网络仿真 …

C++ Qt开发:QItemDelegate自定义代理组件

老规矩&#xff0c;首先推荐好书&#xff1a; Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍…

【RocketMQ笔记01】安装RocketMQ消息队列运行环境

这篇文章&#xff0c;主要介绍如何安装RocketMQ消息队列运行环境。 目录 一、RocketMQ消息队列 1.1、下载RocketMQ 1.2、解压安装包 1.3、配置RocketMQ环境变量 1.4、修改启动脚本 1.5、启动RocketMQ &#xff08;1&#xff09;启动NameServer &#xff08;2&#xff0…

第一届能源电子产业创新大赛太阳能光伏赛道在京顺利完成初赛评审

近日&#xff0c;第一届能源电子产业创新大赛太阳能光伏赛道初赛在北京顺利举行。本次太阳能光伏赛道赛事由工业和信息化部产业发展促进中心、宜宾市人民政府主办&#xff0c;宜宾市经济和信息化局、宜宾高新技术产业园区承办&#xff0c;中国国检测试控股集团股份有限公司协办…

【SpringBoot篇】解决缓存击穿问题② — 基于逻辑过期方式

&#x1f38a;专栏【SpringBoot】 &#x1f354;喜欢的诗句&#xff1a;天行健&#xff0c;君子以自强不息。 &#x1f386;音乐分享【如愿】 &#x1f384;欢迎并且感谢大家指出小吉的问题&#x1f970; 文章目录 &#x1f38d;什么是逻辑过期方式⭐思路&#x1f339;代码 &am…

Vue框架引入Element-Ui

首先已经创建好了 Vue 框架&#xff0c;安装好了 node.js。 没有完成的可按照此博客搭建&#xff1a;搭建Vue项目 之后打开终端&#xff0c;使用命令。 1、命令引入 npm i element-ui -S2、package.json 查看版本 在 package.json 文件里可查看下载好的依赖版本。 3、在 ma…