2016-06-10 22 views
9

Czy istnieje sposób na dodanie niestandardowego atrybutu pola w Odoo? Na przykład każde pole ma atrybut help, w którym można wprowadzić komunikat wyjaśniający pole dla użytkownika. Dlatego chcę dodać atrybut niestandardowy, aby zmienić sposób działania pola dla wszystkich typów pól.Odoo - dodaj niestandardowy atrybut pola?

Chcę dodać do klasy Field, aby wszystkie pola otrzymały ten atrybut. Ale wydaje się, że nie ważne, co robię, Odoo nie widzi, że taki atrybut został dodany.

Gdybym po prostu dodać nowy atrybut niestandardowy lubię:

some_field = fields.Char(custom_att="hello") 

Wtedy to jest po prostu ignorowana. I muszę go odebrać metodą fields_get, która może powrócić żądaną wartość atrybutu (info co robi:

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 
    """ 

więc nazywając ją, nie powraca mój atrybut niestandardowy (to nie zwraca te pierwotnie zdefiniowane przez Odoo chociaż).

próbowałem też aktualizowanie _slots (z małpiej poprawki lub po prostu testuje zmieniając kod) atrybut źródłowy w Field klasy, ale wydaje się, że to za mało. Ponieważ mój atrybut jest nadal ignorowane.

from openerp import fields 

original_slots = fields.Field._slots 

_slots = original_slots 
_slots['custom_att'] = None 

fields.Field._slots = _slots 

Czy ktoś wie, jak poprawnie dodać nowy atrybut niestandardowy dla pola?

Odpowiedz

3

Zakładając v9

Wynik fields_get podsumowanie pól zdefiniowanych na modelu, the code pokazuje, że to będzie tylko dodać atrybut, jeśli opis był wypełniony. Będzie pobrać opis bieżącego pola by calling field.get_description

Więc w celu upewnienia się, że atrybut zostanie wstawiony do tego self.description_attrs trzeba będzie dodać atrybut lub metody, która zaczyna się _description_customatt (customatt części z przykładu) i powróci wymagane dane.

Nie przeprowadzałem żadnych testów, ale można spojrzeć na kod pól i ich atrybutów, które faktycznie zwracają.Na przykład opis atrybut help (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 
+1

Próbowałem to i to działa, choć trzeba również dodać, że atrybut wewnątrz '_slots' słowniku (w klasie' Field'), więc będzie uzyskać wartość domyślną, inaczej Odoo zgłosi błąd. Teraz muszę dowiedzieć się, jak zastosować to bez bezpośredniego modyfikowania kodu źródłowego. – Andrius

0

To jest tylko coś, co możesz zrobić, jeśli uruchamiasz OpenERP/ODOO na swoim własnym serwerze (innymi słowy, nie jest to wersja w chmurze, której kodu nie masz dostępu).

Będziesz musiał zmodyfikować plik <base>/osv/fields.py i dodać swoje zmiany do funkcji field_to_dict w kierunku dolnej części pliku (klasa bazowa _column już oszczędza dodatkowych słów kluczowych argumentów dla Ciebie - przynajmniej w wersji 7.0):

def field_to_dict(model, cr, user, field, context=None): 
    res = {'type': field._type} 
    ... 
    ... 
    for arg in ('string', 'readonly', ...) : 

Gdzieś w tej długiej listy atrybutów trzeba wstawić nazwę, którą są zainteresowani.

Alternatywnie, można aktualizować _column.__init__ zapisać nazwy dodatkowych argumentów i field_to_dict zawierać th em (niesprawdzone):

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 
Powiązane problemy