如何在 Odoo 16 中通过函数创建和管理自定义字段

news2024/11/24 19:42:53

Odoo 几乎为每种功能提供了每种类型的字段。通常,我们为字段定义一个类定义并将其包含在模型中。但是,在某些业务实例中,我们可能需要通过添加新字段从用户界面本身修改模型。在本博客中,让我们研究如何定义自定义字段在视图中的位置以及如何使用函数在模型中创建它。

为了创建字段,我们首先需要使用模型来定义该字段。
 

class CustomField(models.Model): 

"""从用户界面创建新的自定义字段的模型""" 

   _name = 'custom.field' 

   _description = '自定义字段创建' 

   _inherit = 'ir.model.fields' 

   position_field = fields.Many2one('ir.model.fields', string='字段名称') 

   position = fields.Selection([('before', 'Before'), 

                                ('after', 'After')], string='Position', 

                               required=True) 

   model_id = fields.Many2one('ir.model', string='Model', required=True, 

                              index=True, ondelete='cascade', 

                              help="此字段所属的模型") 

   ref_model_id = fields.Many2one('ir.model', string='Model', index=True) 

   field_selection = fields.Char(string="选择选项") 

   relation_field = fields.Many2one('ir.model.fields', string='Related Field') 

   ttype = fields.Selection(string="Field Type", related='field_type') 

   field_type = fields.Selection(selection='get_possible_field_types', 

                                 string='Field Type', required=True) 

   extra_features = fields.Boolean(string="显示额外属性") 

   groups = fields.Many2many('res.groups', 'dynamic_field_creation_id', 

                             'field_id', 'group_id') 

   @api.model 

   def get_possible_field_types(self): 

"""提供所有可用的字段类型,但“one2many”和“reference”字段除外。""" 

       field_list = sorted((key, key) for key in fields.MetaField.by_type) 

       field_list.remove(('one2many', 'one2many')) 

       field_list.remove(('reference', 'reference'))

       返回 field_list 

   @api.onchange('field_type') 

   def onchange_field_type(self):

       如果 self.field_type:

           如果 self.field_type == 'binary':

               返回 {'domain': {'widget': [('name', '=', 'image')]}} 

           elif self.field_type == 'many2many':

               返回 {'domain': { 

                   'widget': [('name', 'in', ['many2many_tags', 'binary'])]}} 

           elif self.field_type == 'selection':

               返回 { 

                   'domain':{ 

                       'widget': [('name', 'in', ['radio', 'priority'])]}} 

           elif self.field_type == 'float':

               返回 {'domain': {'widget': [('name', '=', 'monetary')]}} 

           elif self.field_type == 'many2one':

               返回 {'domain': {'widget': [('name', '=', 'selection')]}} 

           else:

               返回 {'domain': {'widget': [('id', '=', False)]}}

       返回 {'domain': {'widget': [('id', '=', False)]}}

通过继承 Odoo 中字段的基础模型“ir.model.fields”,可以创建自定义模型。因此,可以在自定义模型中使用“ir.model.fields”中的字段。

笔记:

我们必须在自定义模型中重新定义 groups 字段,因为 many2many 字段 dynamic.fields.groups 和 ir.model.fields.groups 使用相同的表和列,这就是我们会收到 500 错误的原因。

为了解决这个问题,我们必须在“res.groups”中定义与我们的自定义模型相关的自定义字段。
 

class ResGroups(models.Model): """继承模型 Res Group 以添加字段来从模型自定义字段中

获取关系"""    _inherit = 'res.groups'    dynamic_field_id = fields.Many2one('custom.fields')



我们必须在自定义模型中指定字段。

position_field:定义要显示的自定义字段。它与“ir.model.fields”相关,是多对一字段。我们可以使用“position_field”来定义自定义字段的视图。

position:定义自定义字段的位置。可选字段有两个值:Before 和 After。自定义字段可以在“position_field”中定位在“Before”或“After”。

model_id:正在定义自定义字段的模型的名称。

field_type:定义字段的类型。这是一个选择字段。在函数“get_possible_field_types”中,将返回选择值。该函数将返回除“one2many”和“reference”之外的所有字段类型。

ref_model_id:如果是关系字段,则用于定义自定义字段和自定义模型之间的关系。

现在让我们检查一下这个定制模型的视图是如何定义的。
 

<?xml version="1.0" encoding="utf-8"?> 

<odoo> 

   <!-- 模型自定义字段的形式 --> 

   <record id='custom_field_view_form' model='ir.ui.view'> 

       <field name="name">custom.fields.view.form</field> 

       <field name="model">custom.field</field> 

       <field name="arch" type="xml"> 

           <form string="自定义字段创建"> 

               <sheet> 

                   <group> 

                       <group string="字段信息"> 

                           <field name="name"/> 

                           <field name="field_description"/> 

                           <field name="state" readonly="1" 

                                  groups="base.group_no_one"/> 

                           <field name="model_id" 

                                  options='{"no_open": True, "no_create": True}'/> 

                           <field name="field_type"/> 

                           <field name="field_selection" 

                                  placeholder="[('blue', 'Blue'),('yellow', 'Yellow')]" 

                                  attrs="{'required': [('field_type','in',['selection','reference'])], 

                                                 'readonly': [('field_type','not in',['selection','reference'])], 

                                                 'invisible': [('field_type','not in',['selection','reference'])]}"/> 

                           <field name="ref_model_id" 

                                  options='{"no_open": True, "no_create": True}' 

                                  attrs="{'required': [('field_type','in',['many2one','many2many'])], 

                                                             'readonly': [('field_type','not in',['many2one','many2many'])], 

                                                             'invisible': [('field_type','not in',['many2one','many2many'])]}"/> 

                           <field name="required"/> 

                       </group> 

                       <group string="Position"> 

                           <field name="position_field" 

                                  options='{"no_open": True, "no_create": True}'/> 

                           <field name="position"/> 

                       </group> 

                   </group> 

                   <group string="额外属性"> 

                       <group> 

                           <field name="extra_features"/> 

                       </group> 

                       <group attrs="{'invisible': [('extra_features', '=', False)]}">

                           <field name="help"/> 

                       </group> 

                       <group attrs="{'invisible': [('extra_features', '=', False)]}"> 

                           <field name="readonly"/> 

                           <field name="store"/> 

                           <field name="index"/> 

                           <field name="copied"/> 

                       </group> 

                   </group> 

               </sheet> 

               <footer> 

                   <button name="action_create_custom_field" 

                           string="创建字段" type="object" 

                           class="oe_highlight"/> 

                   <button string="取消" class="oe_link" special="cancel"/> 

               </footer> 

           </form> 

       </field> 

   </record> 

   <!-- 菜单创建自定义字段的操作 --> 

   <record id='action_custom_fields' model='ir.actions.act_window'> 

       <field name="name">创建自定义字段</field> 

       <field name="res_model">custom.field</field> 

       <field name="view_mode">form</field> 

       <field name="view_id" ref="custom_field_view_form"/> 

       <field name="target">new</field> 

   </record> 

   <!-- 创建字段的菜单项 --> 

   <menuitem 

       id="menu_custom_field" 

       name="创建字段" 

       parent="sale.sale_menu_root" 

       action="action_custom_fields" 

       serial="10"/> 

</odoo>


现在,让我们为按钮“CREATE FIELD”创建功能来创建自定义字段。
 

def action_create_custom_field(self): 

"""用于创建自定义字段的按钮操作""" 

   self.env['ir.model.fields'].sudo().create({'name': self.name, 

                                              'field_description': self.field_description, 

                                              'model_id': self.model_id.id, 

                                              'ttype': self.field_type, 

                                              'relation': self.ref_model_id.model, 

                                              'required': self.required, 

                                              'index': self.index, 

                                              'store': self.store, 

                                              'help': self.help, 

                                              'readonly': self.readonly, 

                                              'selection': self.field_selection, 

                                              'copied': self.copied, 

                                              }) 

   inherit_id = self.env.ref('sale.view_order_form') 

   arch_base = _('<?xml version="1.0"?>' 

                 '<data>' 

                 '<field name="%s" position="%s">' 

                 '<field name="%s"/>' 

                 '</field>' 

                 '</data>') % ( 

                   self.position_field.name, self.position, self.name) 

   self.env['ir.ui.view'].sudo().create( 

       {'name': 'sale.custom.field.%s' % self.name, 

        'type': 'form', 

        'model': 'sale.order', 

        'mode': 'extension', 

        'inherit_id': inherit_id.id, 

        'arch_base': arch_base, 

        'active': True}) 

   return { 

       'type': 'ir.actions.client', 

       'tag': 'reload', 

   }

“create”方法用于模型“ir.model.fields”内部生成此函数描述中的字段。“sale.view_order_form”是员工表单视图的外部id。在此特定视图中的“Payment Term.”字段之后,我们必须定义自定义字段“Custom Field”的视图。因此,我们将从“inherit_id”中获取视图记录的id。接下来,我们将使用“ir.ui.view”中的“create”函数创建一个继承视图“sale.view_order_form”的新视图

为了向销售订单表单视图添加自定义字段,我们可以单击创建按钮。
有时,需要从用户界面创建一些模型字段。在这种情况下,我们可以使用此方法在模型内创建自定义字段。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智能数字人系统的主要功能

智能数字人系统或虚拟数字人系统&#xff0c;是指利用人工智能技术构建的虚拟人物形象&#xff0c;能够与人进行自然交互的系统。数字人系统的主要功能包括以下几个方面。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1. 语言理解与…

从游戏到营销:抽卡机小程序的多维度应用探索

在数字化时代&#xff0c;小程序作为一种轻量级、即用即走的应用形态&#xff0c;正逐步渗透到人们生活的方方面面。其中&#xff0c;抽卡机小程序以其独特的趣味性和互动性&#xff0c;不仅在游戏领域大放异彩&#xff0c;更在营销领域展现出广阔的应用前景。本文将从游戏起源…

RocketMQ实战:一键在docker中搭建rocketmq和doshboard环境

在本篇博客中&#xff0c;我们将详细介绍如何在 Docker 环境中一键部署 RocketMQ 和其 Dashboard。这个过程基于一个预配置的 Docker Compose 文件&#xff0c;使得部署变得简单高效。 项目介绍 该项目提供了一套 Docker Compose 配置&#xff0c;用于快速部署 RocketMQ 及其…

【面向就业的Linux基础】从入门到熟练,探索Linux的秘密(七)-shell语法(5)

shell语法的一些知识和练习&#xff0c;可以当作笔记收藏一下&#xff01;&#xff01; 文章目录 前言 一、shell 二、shell语法 1.文件重定向 2.引入外部脚本 3.作业 总结 前言 shell语法的一些知识和练习&#xff0c;可以当作笔记收藏一下&#xff01;&#xff01; 提示&…

01:Linux的基本命令

Linux的基本命令 1、常识1.1、Linux的隐藏文件1.2、绝对路径与相对路径 2、基本命令2.1、ls2.2、cd2.3、pwd / mkdir / mv / touch / cp / rm / cat / rmdir2.4、ln2.5、man2.6、apt-get 本教程是使用的是Ubuntu14.04版本。 1、常识 1.1、Linux的隐藏文件 在Linux中&#xf…

全网首发-RocketMQ 4.0实现完美灰度发布方案

一、背景 为了控制发版带来的影响面等问题&#xff0c;我们公司基建团队自研灰度发布流程&#xff0c;目前几乎所有服务发版都会严格先走灰度发布验证再上线。当前已支持http、gRPC等接口调用方式进行灰度流量转发&#xff0c;使用消息队列进行业务实现的场景的暂不支持。 ps:…

优思学院|亚马逊如何因六西格玛而取得成功?

前言 上星期三&#xff0c;亚马逊&#xff08;Amazon&#xff09;市值首次超过2万亿美元&#xff0c;成为世界第五大巿值最高的企业&#xff0c;它是全球最大的互联网线上零售商之一。然而&#xff0c;或者你并不知道&#xff0c;亚马逊也是众多因六西格玛而取得成功的公司之一…

企业自身数据保护技巧你知道多少?用堡垒机可以实现吗?

随着企业数字化转型&#xff0c;越来越多的企业开始重视企业自身数据的安全&#xff0c;开始寻找保障数据安全的方法技巧。不少人在问&#xff0c;企业自身数据保护技巧有哪些&#xff1f;你知道吗&#xff1f;用堡垒机可以实现吗&#xff1f;今天我们来简单聊聊。 企业自身数据…

【udp报文】udp报文未自动分片,报文过长被拦截问题定位

问题现象 某局点出现一个奇怪的现象&#xff0c;客户端给服务端发送消息&#xff0c;服务端仅能收到小部分消息&#xff0c;大部分消息从客户端发出后&#xff0c;服务端都未收到。 问题定位 初步分析 根据现象初步分析&#xff0c;有可能是网络原因导致消息到服务端不可达&a…

湿法工艺特氟龙刻蚀清洗架 耐强酸四氟晶圆盒应用半导体行业

四氟花篮又叫四氟清洗花蓝 、 特氟龙卡匣、 特氟龙晶舟盒、特氟龙晶圆盒、特氟龙晶片清洗架、特氟龙晶圆架、特氟龙刻蚀花篮、特氟龙刻蚀清洗架、PTFE显影花篮 。四氟花篮在半导体、多晶硅、新能源、新材料、太阳能等行业广泛应用 。具备耐腐蚀性、耐高温性、不粘性、绝缘性、防…

SAR目标检测

Multi-Stage with Filter Augmentation 多阶段滤波器增强(MSFA) 对SAR合成孔径雷达目标检测性能的改善 MSFA ON SAR 传统方法: 预训练:传统方法开始于在通用数据集上预训练一个基础模型。 微调:这个预训练的模型会被微调以适应特定的SAR图像&#xff0c;试图缩小域间的差距 …

应急灯、车库灯毫米波雷达人体存在传感器模块,超低功耗uA级别,飞睿智能LED照明控制,抗干扰、远距离、参数可调

在智能化、自动化的浪潮中&#xff0c;我们的生活正在经历一场前所未有的创新。无论是智能家居、智能交通还是智能安防&#xff0c;科技的力量正在悄然改变着我们的生活。而在这场创新中&#xff0c;毫米波雷达人体存在传感器模块凭借其独特的优势&#xff0c;成为了智能设备中…

秋招——MySQL补充——MySQL是如何加行级锁

文章目录 引言正文什么SQL语句会加行级锁查询操作增加对应的行级锁事务的写法 update和delete修改操作也会增加行级锁 行级锁有哪些种类记录锁间隙锁Next-Key锁 MySQL是如何加行级锁&#xff1f;唯一索引等值查询查询记录是存在的查询记录是不存在的 唯一索引范围查找针对大于或…

一个暑假如何学习单片机

一个暑假是学习和掌握单片机基础知识的良好时机。以下是一个关于如何在暑假期间学习单片机的建议计划&#xff1a; 1. 了解基础知识 查阅资料&#xff1a;首先&#xff0c;了解单片机是什么&#xff0c;它的工作原理、常见型号和应用场景。学习编程语言&#xff1a;单片机通常…

【区块链+基础设施】蜀信链 | FISCO BCOS应用案例

蜀信链是在四川省经济和信息化厅指导下&#xff0c;在四川省区块链行业协会组织下&#xff0c;由全省区块链相关从业与应用机构 共同参与建设和运营的区域性区块链基础设施&#xff0c;通过多方协同&#xff0c;共同打造合作共赢的区块链产业生态。 蜀信链区块链服务生态秉承“…

移动网络捕获在数字化转型中的重要性

数字化转型重新定义了企业运营和与客户互动的方式。它为组织提供价值的方式带来了根本性的转变&#xff0c;使流程更易于访问、更高效、更具协作性和更安全。然而&#xff0c;跟上不断发展的数字环境可能是一项挑战&#xff0c;而未能接受数字化转型的企业则面临被淘汰的风险。…

农作物监测新利器:免费可视化工具让数据说话

从传统的“靠天吃饭”到如今的“智慧农业”&#xff0c;数据成为了驱动这一转变的关键力量。随着物联网、大数据、云计算等技术的深入应用&#xff0c;农业生产过程中的各类数据如雨后春笋般涌现。从土壤湿度、光照强度到作物生长周期、病虫害情况等&#xff0c;这些数据背后隐…

电路模型和电路定律

电路---为了某种需要由某些电工设备或元件按一定方式组合起来的电流的通路 实际电路的两个作用 1.电能的传输&#xff0c;分配和转换 2.传递和处理信号 电路中的几个基本概念 激励---电源或信号源的电压或电流&#xff0c;也称为输入 响应---由激励在电路各部分产生的电流…

基于ESP32 IDF的WebServer实现以及OTA固件升级实现记录(三)

经过前面两篇的前序铺垫&#xff0c;对webserver以及restful api架构有了大体了解后本篇描述下最终的ota实现的代码以及调试中遇到的诡异bug。 eps32的实际ota实现过程其实esp32官方都已经基本实现好了&#xff0c;我们要做到无非就是把要升级的固件搬运到对应ota flash分区里面…

应用密码学—(扩展)欧几里得、DES、RSA、SHA-1算法

1. 欧几里得算法 1.1 分析算法的实现原理 欧几里德&#xff08;Euclid&#xff09;算法&#xff0c;也既常说的“辗转相除法”&#xff0c;公式为gcd(m, n) { return gcd(n, m%n); }&#xff0c;对于任意两个正整数m、n&#xff0c;每次求的一个数字r m % n&#xff0c;然后把…