Odoo - 添加自定义字段属性?
Odoo - add custom field attribute?
有没有办法在 Odoo 中添加自定义字段属性?例如,每个字段都有属性 help
,您可以在其中输入为用户解释该字段的消息。所以我想添加自定义属性,这样会改变字段对所有类型字段的作用方式。
我想添加到 Field
class,这样所有字段都会获得该属性。但似乎无论我做什么,Odoo 都看不到添加了这样的属性。
如果我简单地添加新的自定义属性,例如:
some_field = fields.Char(custom_att="hello")
那就干脆无视了。我需要通过方法 fields_get
获取它,它可以 return 想要的属性值(信息它的作用:
def fields_get(self, cr, user, allfields=None, context=None, write_access=True, attributes=None):
""" fields_get([fields][, attributes])
Return the definition of each field.
The returned value is a dictionary (indiced by field name) of
dictionaries. The _inherits'd fields are included. The string, help,
and selection (if present) attributes are translated.
:param allfields: list of fields to document, all if empty or not provided
:param attributes: list of description attributes to return for each field, all if empty or not provided
"""
所以调用它,不会 return 我的自定义属性(它确实 return Odoo 最初定义的属性)。
我还尝试更新 _slots
(使用猴子补丁或仅通过更改源代码进行测试) Field
class 中的属性,但似乎还不够。因为我的属性还是被忽略了。
from openerp import fields
original_slots = fields.Field._slots
_slots = original_slots
_slots['custom_att'] = None
fields.Field._slots = _slots
有谁知道如何正确地为字段添加新的自定义属性?
只有在您自己的服务器上 运行 OpenERP/ODOO 才能做到这一点(换句话说,不是您无法访问其代码的云版本)。
您需要修改 <base>/osv/fields.py
文件并将您的更改添加到文件底部的 field_to_dict
函数(基础 _column
class 已经保存为您提供额外的关键字参数——至少在 7.0 版中是这样):
def field_to_dict(model, cr, user, field, context=None):
res = {'type': field._type}
...
...
for arg in ('string', 'readonly', ...) :
您需要在长长的属性列表中的某处插入您感兴趣的属性的名称。
或者,您可以更新 _column.__init__
以保存额外参数的名称,并更新 field_to_dict
以包含它们(未经测试):
diff -r a30d30db3cd9 osv/fields.py
--- a/osv/fields.py Thu Jun 09 17:18:29 2016 -0700
+++ b/osv/fields.py Mon Jun 13 18:11:26 2016 -0700
@@ -116,23 +116,24 @@ class _column(object):
self._context = context
self.write = False
self.read = False
self.view_load = 0
self.select = select
self.manual = manual
self.selectable = True
self.group_operator = args.get('group_operator', False)
self.groups = False # CSV list of ext IDs of groups that can access this field
self.deprecated = False # Optional deprecation warning
- for a in args:
- if args[a]:
- setattr(self, a, args[a])
+ self._user_args = ()
+ for name, value in args:
+ setattr(self, name, value or False)
+ self._user_args += name
def restart(self):
pass
def set(self, cr, obj, id, name, value, user=None, context=None):
cr.execute('update '+obj._table+' set '+name+'='+self._symbol_set[0]+' where id=%s', (self._symbol_set[1](value), id))
def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None):
raise Exception(_('undefined get method !'))
@@ -1559,20 +1560,22 @@ def field_to_dict(model, cr, user, field
res['o2m_order'] = field._order or False
if isinstance(field, many2many):
(table, col1, col2) = field._sql_names(model)
res['m2m_join_columns'] = [col1, col2]
res['m2m_join_table'] = table
for arg in ('string', 'readonly', 'states', 'size', 'group_operator', 'required',
'change_default', 'translate', 'help', 'select', 'selectable', 'groups',
'deprecated', 'digits', 'invisible', 'filters'):
if getattr(field, arg, None):
res[arg] = getattr(field, arg)
+ for arg in field._user_args:
+ res[arg] = getattr(field, arg)
if hasattr(field, 'selection'):
if isinstance(field.selection, (tuple, list)):
res['selection'] = field.selection
else:
# call the 'dynamic selection' function
res['selection'] = field.selection(model, cr, user, context)
if res['type'] in ('one2many', 'many2many', 'many2one'):
res['relation'] = field._obj
res['domain'] = field._domain(model) if callable(field._domain) else field._domain
假设 v9
fields_get
的结果是模型上定义的字段的摘要,the code shows that it will only add the attribute if the description was filled. It will fetch the description of the current field by calling field.get_description
因此,为了确保您的属性被插入到此 self.description_attrs
中,您需要添加一个以 _description_customatt
开头的属性或方法(customatt
部分来自您的示例)并将 return 所需的数据。
我没有 运行 对此进行任何测试,但您可以查看字段的代码及其实际 return 的属性。例如帮助属性描述(src)
def _description_help(self, env):
if self.help and env.lang:
model_name = self.base_field.model_name
field_help = env['ir.translation'].get_field_help(model_name)
return field_help.get(self.name) or self.help
return self.help
有没有办法在 Odoo 中添加自定义字段属性?例如,每个字段都有属性 help
,您可以在其中输入为用户解释该字段的消息。所以我想添加自定义属性,这样会改变字段对所有类型字段的作用方式。
我想添加到 Field
class,这样所有字段都会获得该属性。但似乎无论我做什么,Odoo 都看不到添加了这样的属性。
如果我简单地添加新的自定义属性,例如:
some_field = fields.Char(custom_att="hello")
那就干脆无视了。我需要通过方法 fields_get
获取它,它可以 return 想要的属性值(信息它的作用:
def fields_get(self, cr, user, allfields=None, context=None, write_access=True, attributes=None):
""" fields_get([fields][, attributes])
Return the definition of each field.
The returned value is a dictionary (indiced by field name) of
dictionaries. The _inherits'd fields are included. The string, help,
and selection (if present) attributes are translated.
:param allfields: list of fields to document, all if empty or not provided
:param attributes: list of description attributes to return for each field, all if empty or not provided
"""
所以调用它,不会 return 我的自定义属性(它确实 return Odoo 最初定义的属性)。
我还尝试更新 _slots
(使用猴子补丁或仅通过更改源代码进行测试) Field
class 中的属性,但似乎还不够。因为我的属性还是被忽略了。
from openerp import fields
original_slots = fields.Field._slots
_slots = original_slots
_slots['custom_att'] = None
fields.Field._slots = _slots
有谁知道如何正确地为字段添加新的自定义属性?
只有在您自己的服务器上 运行 OpenERP/ODOO 才能做到这一点(换句话说,不是您无法访问其代码的云版本)。
您需要修改 <base>/osv/fields.py
文件并将您的更改添加到文件底部的 field_to_dict
函数(基础 _column
class 已经保存为您提供额外的关键字参数——至少在 7.0 版中是这样):
def field_to_dict(model, cr, user, field, context=None):
res = {'type': field._type}
...
...
for arg in ('string', 'readonly', ...) :
您需要在长长的属性列表中的某处插入您感兴趣的属性的名称。
或者,您可以更新 _column.__init__
以保存额外参数的名称,并更新 field_to_dict
以包含它们(未经测试):
diff -r a30d30db3cd9 osv/fields.py
--- a/osv/fields.py Thu Jun 09 17:18:29 2016 -0700
+++ b/osv/fields.py Mon Jun 13 18:11:26 2016 -0700
@@ -116,23 +116,24 @@ class _column(object):
self._context = context
self.write = False
self.read = False
self.view_load = 0
self.select = select
self.manual = manual
self.selectable = True
self.group_operator = args.get('group_operator', False)
self.groups = False # CSV list of ext IDs of groups that can access this field
self.deprecated = False # Optional deprecation warning
- for a in args:
- if args[a]:
- setattr(self, a, args[a])
+ self._user_args = ()
+ for name, value in args:
+ setattr(self, name, value or False)
+ self._user_args += name
def restart(self):
pass
def set(self, cr, obj, id, name, value, user=None, context=None):
cr.execute('update '+obj._table+' set '+name+'='+self._symbol_set[0]+' where id=%s', (self._symbol_set[1](value), id))
def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None):
raise Exception(_('undefined get method !'))
@@ -1559,20 +1560,22 @@ def field_to_dict(model, cr, user, field
res['o2m_order'] = field._order or False
if isinstance(field, many2many):
(table, col1, col2) = field._sql_names(model)
res['m2m_join_columns'] = [col1, col2]
res['m2m_join_table'] = table
for arg in ('string', 'readonly', 'states', 'size', 'group_operator', 'required',
'change_default', 'translate', 'help', 'select', 'selectable', 'groups',
'deprecated', 'digits', 'invisible', 'filters'):
if getattr(field, arg, None):
res[arg] = getattr(field, arg)
+ for arg in field._user_args:
+ res[arg] = getattr(field, arg)
if hasattr(field, 'selection'):
if isinstance(field.selection, (tuple, list)):
res['selection'] = field.selection
else:
# call the 'dynamic selection' function
res['selection'] = field.selection(model, cr, user, context)
if res['type'] in ('one2many', 'many2many', 'many2one'):
res['relation'] = field._obj
res['domain'] = field._domain(model) if callable(field._domain) else field._domain
假设 v9
fields_get
的结果是模型上定义的字段的摘要,the code shows that it will only add the attribute if the description was filled. It will fetch the description of the current field by calling field.get_description
因此,为了确保您的属性被插入到此 self.description_attrs
中,您需要添加一个以 _description_customatt
开头的属性或方法(customatt
部分来自您的示例)并将 return 所需的数据。
我没有 运行 对此进行任何测试,但您可以查看字段的代码及其实际 return 的属性。例如帮助属性描述(src)
def _description_help(self, env):
if self.help and env.lang:
model_name = self.base_field.model_name
field_help = env['ir.translation'].get_field_help(model_name)
return field_help.get(self.name) or self.help
return self.help