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

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

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

class CustomField(models.Model):
"""Model for creating a new custom field from the user interface"""
   _name = 'custom.field'
   _description = 'Custom Field Creation'
   _inherit = 'ir.model.fields'
   position_field = fields.Many2one('ir.model.fields', string='Field Name')
   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="The model this field belongs to")
   ref_model_id = fields.Many2one('ir.model', string='Model', index=True)
   field_selection = fields.Char(string="Selection Options")
   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="Show Extra Properties")
   groups = fields.Many2many('res.groups', 'dynamic_field_creation_id',
                             'field_id', 'group_id')
   @api.model
   def get_possible_field_types(self):
"""Provide all field types that are available, with the exception of "one2many" and "reference" fields.."""
       field_list = sorted((key, key) for key in fields.MetaField.by_type)
       field_list.remove(('one2many', 'one2many'))
       field_list.remove(('reference', 'reference'))
       return field_list
   @api.onchange('field_type')
   def onchange_field_type(self):
       if self.field_type:
           if self.field_type == 'binary':
               return {'domain': {'widget': [('name', '=', 'image')]}}
           elif self.field_type == 'many2many':
               return {'domain': {
                   'widget': [('name', 'in', ['many2many_tags', 'binary'])]}}
           elif self.field_type == 'selection':
               return {
                   'domain': {
                       'widget': [('name', 'in', ['radio', 'priority'])]}}
           elif self.field_type == 'float':
               return {'domain': {'widget': [('name', '=', 'monetary')]}}
           elif self.field_type == 'many2one':
               return {'domain': {'widget': [('name', '=', 'selection')]}}
           else:
               return {'domain': {'widget': [('id', '=', False)]}}
       return {'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):
"""Inherited the model Res Group for adding a field to get the relation
from the model custom fields"""
   _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>
   <!-- Form of the model custom field -->
   <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="Custom Field Creation">
               <sheet>
                   <group>
                       <group string="Field Info">
                           <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="Extra Properties">
                       <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="Create Field" type="object"
                           class="oe_highlight"/>
                   <button string="Cancel" class="oe_link" special="cancel"/>
               </footer>
           </form>
       </field>
   </record>
   <!-- Action for the menu Create Custom Fields -->
   <record id='action_custom_fields' model='ir.actions.act_window'>
       <field name="name">Create Custom Fields</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>
   <!-- Menu Item for the Create Fields -->
   <menuitem
       id="menu_custom_field"
       name="Create Fields"
       parent="sale.sale_menu_root"
       action="action_custom_fields"
       sequence="10"/>
</odoo>


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

def action_create_custom_field(self):
"""Button action for creating custom field"""
   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”的新视图 

为了向销售订单表单视图添加自定义字段,我们可以单击创建按钮。

有时,需要从用户界面创建一些模型字段。在这种情况下,我们可以使用此方法在模型内创建自定义字段。 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

奔跑的蜗牛..

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

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

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

打赏作者

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

抵扣说明:

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

余额充值