2016-06-10 21 views
9

Gibt es eine Möglichkeit, benutzerdefinierte Feldattribute in Odoo hinzuzufügen? Zum Beispiel hat jedes Feld das Attribut help, in dem Sie eine Nachricht eingeben können, die das Feld für den Benutzer erklärt. Daher möchte ich ein benutzerdefiniertes Attribut hinzufügen, damit sich das Feld für alle Arten von Feldern ändert.Odoo - benutzerdefiniertes Feldattribut hinzufügen?

Ich möchte in Field Klasse hinzufügen, damit alle Felder dieses Attribut erhalten würden. Aber egal, was ich mache, Odoo sieht nicht, dass ein solches Attribut hinzugefügt wurde.

Wenn ich einfach neue benutzerdefinierte Attribut hinzufügen möchte:

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

Dann wird es einfach ignoriert. Und ich brauche es durch fields_get Verfahren aufgenommen werden sollen, die gewünschten Attributwert zurückgeben kann (info, was sie tut:

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

es so nennen, kehrt nicht meine benutzerdefinierte Attribute (es die, die zurückkehrt ursprünglich definiert durch Odoo obwohl).

ich habe auch versucht _slots (mit Affen-Patch zu aktualisieren oder einfach nur testen von Quellcode) Attribut in Field Klasse zu ändern, aber es scheint, es ist nicht genug. Weil mein Attribut noch ignoriert.

from openerp import fields 

original_slots = fields.Field._slots 

_slots = original_slots 
_slots['custom_att'] = None 

fields.Field._slots = _slots 

Kann jemand neues benutzerdefiniertes Attribut für Feld richtig hinzufügen?

Antwort

3

Unter der Annahme, v9

Das Ergebnis fields_get ist eine Zusammenfassung der Felder auf einem Modell definiert, the code zeigt, dass es nur das Attribut hinzufügen, wenn die Beschreibung gefüllt war. Es wird die Beschreibung des aktuellen Feldes by calling field.get_description

Also, um holen, um sicherzustellen, dass das Attribut in diesen self.description_attrs eingefügt wird Sie ein Attribut oder Methode muss hinzufügen, die mit _description_customatt (customatt Teil aus Ihrem Beispiel) beginnt und kehren die erforderlichen Daten.

Ich habe keine Tests für diese durchgeführt, aber Sie können den Code für die Felder und ihre Attribute sehen, was sie tatsächlich zurückgeben.Zum Beispiel der Hilfe Attributbeschreibung (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

habe ich versucht, diese und es funktioniert, obwohl Sie müssen auch das Attribut innerhalb '_slots' Wörterbuch hinzufügen (in' Field' Klasse), so wird es Standardwert zu erhalten, Andernfalls wird Odoo einen Fehler melden. Jetzt muss ich herausfinden, wie man das anwendet, ohne den Quellcode direkt zu verändern. – Andrius

0

Dies können Sie nur tun, wenn Sie OpenERP/ODOO auf Ihrem eigenen Server ausführen (also nicht die Cloud-Version, auf deren Code Sie nicht zugreifen können).

Sie müssen die <base>/osv/fields.py Datei und fügen Sie Ihre Änderungen an der field_to_dict Funktion gegenüber dem Ende der Datei (die Basis _column Klasse bereits spart zusätzliche Keyword-Argumente für Sie da - zumindest in der Version 7.0) ändern:

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

Irgendwo in dieser langen Liste der Attribute müssen Sie den Namen des einen sind Sie interessiert einzufügen.

Alternativ Sie _column.__init__ aktualisieren könnten die Namen der zusätzlichen Argumente zu speichern und field_to_dict th enthalten em (ungetestet):

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