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

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”的新视图

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奔跑的蜗牛..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值