2016-06-10 55 views
9

C'è un modo per aggiungere un attributo di campo personalizzato in Odoo? Ad esempio, ogni campo ha attributo help in cui è possibile inserire un messaggio che spiega il campo per l'utente. Quindi voglio aggiungere un attributo personalizzato, in modo che cambi il modo in cui il campo agisce per tutti i tipi di campi.Odoo: aggiungi un attributo del campo personalizzato?

Voglio aggiungere nella classe Field, in modo che tutti i campi ottengano quell'attributo. Ma sembra che non importa quello che faccio, Odoo non vede che tale attributo è stato aggiunto.

Se ho semplicemente aggiungo nuova personalizzato attribuiscono piace:

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

, allora è semplicemente ignorato. E ne ho bisogno per essere prelevati con il metodo fields_get, che può restituire valore di attributo desiderato (informazioni che cosa fa:

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

Così definendolo, non restituire il mio attributo personalizzato (si fa ritorno a quelli originariamente definiti dalla vudù però).

ho anche provato ad aggiornare _slots (con la patch scimmia o solo test modificando il codice attributo di origine) in Field di classe, ma sembra non basta. Perché il mio attributo viene ancora ignorato.

from openerp import fields 

original_slots = fields.Field._slots 

_slots = original_slots 
_slots['custom_att'] = None 

fields.Field._slots = _slots 

Qualcuno sa come aggiungere correttamente un nuovo attributo personalizzato per il campo?

risposta

3

Supponendo v9

Il risultato di fields_get è la sintesi di campi definiti su un modello, the code mostra che sarà solo aggiungere l'attributo se la descrizione è stata riempita. Esso preleverà la descrizione del campo corrente by calling field.get_description

Così, al fine di garantire che l'attributo viene inserito in questo self.description_attrs è necessario aggiungere un attributo o un metodo che inizia con _description_customatt (customatt parte dal vostro esempio) e restituirà i dati richiesti

Non ho eseguito alcun test per questo, ma puoi vedere il codice per i campi e i loro attributi che cosa effettivamente restituiscono.Per esempio la descrizione aiuto dell'attributo (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

Ho provato questo e funziona, anche se è necessario aggiungere, inoltre, che l'attributo all'interno 'dizionario _slots' (in classe' Field'), in modo da otterrà valore di default, altrimenti Odoo genererà un errore. Ora ho bisogno di capire come applicare questo senza modificare direttamente il codice sorgente. – Andrius

0

Questo è solo qualcosa che è possibile fare se si esegue OpenERP/ODOO sul proprio server (in altre parole, non la versione cloud di cui non è possibile accedere al codice).

Sarà necessario modificare il file <base>/osv/fields.py e aggiungere le modifiche alla funzione field_to_dict verso la fine del file (la classe base _column salva già argomenti extra di parole chiave per voi - almeno nella versione 7.0):

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

da qualche parte in quel lungo elenco di attributi è necessario inserire il nome di colui che ti interessa.

in alternativa, è possibile aggiornare _column.__init__ per salvare i nomi degli argomenti extra, e field_to_dict per includere ° em (non testata):

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