Odoo-добавить атрибут настраиваемого поля?
есть ли способ добавить пользовательский атрибут поля в Odoo? Например каждое поле имеет атрибут help
где вы можете ввести сообщение, в поле для пользователя. Поэтому я хочу добавить пользовательский атрибут, чтобы изменить способ действия поля для всех типов полей.
Я хочу добавить в Field
class, поэтому все поля получат этот атрибут. Но, похоже, что бы я ни делал, оду не видит, что такой атрибут был добавлен.
если я просто добавлю новый пользовательский атрибут типа:
some_field = fields.Char(custom_att="hello")
тогда это просто игнорируется. И мне нужно, чтобы он был подобран методом fields_get
, который может возвращать значение атрибута wanted (информация о том, что он делает:
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
"""
таким образом, вызывая его, не возвращает мой пользовательский атрибут (он возвращает те, которые первоначально были определены Odoo).
Я также попытался обновить _slots
(с патчем обезьяны или просто тестирование путем изменения исходного кода) атрибут Field
класс, но кажется, этого недостаточно. Потому что мой атрибут по-прежнему игнорируется.
from openerp import fields
original_slots = fields.Field._slots
_slots = original_slots
_slots['custom_att'] = None
fields.Field._slots = _slots
кто-нибудь знает, как правильно добавить новый пользовательский атрибут для поля?
2 ответов
предполагая v9
результат fields_get
- это сводка полей, определенных на модели,код показывает, что он добавит атрибут только в том случае, если описание было заполнено. Он будет получать описание текущего поля по телефону field.get_description
Итак, чтобы гарантировать, что ваш атрибут будет вставлен в это self.description_attrs
нужно добавить атрибут или метод, который начинается с _description_customatt
(customatt
часть из вашего примера) и верните необходимые данные.
Я не запускал никаких тестов для этого, но вы можете посмотреть код для полей и их атрибутов, которые они фактически возвращают. Например, описание атрибута справки (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
это только то, что вы можете сделать, если вы запустите OpenERP/ODOO на своем собственном сервере (другими словами, не облачную версию, код которой вы не можете получить доступ).
вам нужно будет изменить <base>/osv/fields.py
файл и добавьте свои изменения в field_to_dict
функция в нижней части файла (база _column
класс уже сохраняет дополнительные аргументы ключевых слов для вас-по крайней мере, в версии 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