Merge lp:~openerp-dev/openobject-server/trunk-bug-795443-xrg into lp:openobject-server

Proposed by xrg
Status: Work in progress
Proposed branch: lp:~openerp-dev/openobject-server/trunk-bug-795443-xrg
Merge into: lp:openobject-server
Diff against target: 151 lines (+75/-54)
1 file modified
openerp/osv/orm.py (+75/-54)
To merge this branch: bzr merge lp:~openerp-dev/openobject-server/trunk-bug-795443-xrg
Reviewer Review Type Date Requested Status
Vo Minh Thu (community) Needs Information
Review via email: mp+64133@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Vo Minh Thu (thu) wrote :

I don't understand why the default_props is used after the _inherits.keys() lookup (i.e. why default_pros is not in remaining_fields).

review: Needs Information
Revision history for this message
Olivier Dony (Odoo) (odo-openerp) wrote :

I don't know if __ignore_ir_values is a good idea, because we probably can't use it during installation. Some ir.values record are specifically used to provide defaults, even during installation of module data and demo.
For example the database installation language is put as an ir.values default for res.partner language, and we rely on it to properly initialize all demo partners. WDYT?

Unmerged revisions

3453. By OpenERP buildbot

orm: refactor orm.default_get() to avoid redundant computations

In default_get(), we need to evaluate the default value of each field,
in an order of resolution. The previous implementation did all the passes
regardless of the result of the previous step, and then dict.update()
the results.

Now, resolve from most-significant to least, trying only the remaining
fields at each step.
Also, have a provision for totally ignoring defaults from ir.values,
because they should not be considered when loading initial data.
(cherry picked from commit ad2cc4f179bbcfd455d8f08a8b7758ca375a1b89)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openerp/osv/orm.py'
2--- openerp/osv/orm.py 2011-05-27 12:32:36 +0000
3+++ openerp/osv/orm.py 2011-06-10 09:31:58 +0000
4@@ -1122,6 +1122,8 @@
5 contents. This can also be selectively overriden by passing a field-specific flag
6 in the form ``bin_size_XXX: True/False`` where ``XXX`` is the name of the field.
7 Note: The ``bin_size_XXX`` form is new in OpenERP v6.0.
8+ If the ``__ignore_ir_values`` is passed and is positive,
9+ defaults will NOT be looked up in ir.values
10 :return: dictionary of the default values (set on the object model class, through user preferences, or in the context)
11 """
12 # trigger view init hook
13@@ -1131,13 +1133,64 @@
14 context = {}
15 defaults = {}
16
17- # get the default values for the inherited fields
18- for t in self._inherits.keys():
19- defaults.update(self.pool.get(t).default_get(cr, uid, fields_list,
20- context))
21-
22- # get the default values defined in the object
23- for f in fields_list:
24+ # Most significant: get the default values from the context
25+ for f in fields_list:
26+ if ('default_' + f) in context:
27+ defaults[f] = context['default_' + f]
28+
29+ # Next significant:
30+ # get the default values set by the user and override the default
31+ # values defined in the object
32+ ir_values_obj = self.pool.get('ir.values')
33+ if context.get('__ignore_ir_values', False):
34+ res = []
35+ else:
36+ res = ir_values_obj.get(cr, uid, 'default', False, [self._name])
37+
38+ for id, field, field_value in res:
39+ if field in defaults or (field not in fields_list):
40+ continue
41+
42+ fld_def = (field in self._columns) and self._columns[field] or self._inherit_fields[field][2]
43+ if fld_def._type in ('many2one', 'one2one'):
44+ obj = self.pool.get(fld_def._obj)
45+ if not obj.search(cr, uid, [('id', '=', field_value or False)]):
46+ continue
47+ if fld_def._type in ('many2many'):
48+ obj = self.pool.get(fld_def._obj)
49+ field_value2 = []
50+ for i in range(len(field_value)):
51+ if not obj.search(cr, uid, [('id', '=',
52+ field_value[i])]):
53+ continue
54+ field_value2.append(field_value[i])
55+ field_value = field_value2
56+ if fld_def._type in ('one2many'):
57+ obj = self.pool.get(fld_def._obj)
58+ field_value2 = []
59+ for i in range(len(field_value)):
60+ field_value2.append({})
61+ for field2 in field_value[i]:
62+ if field2 in obj._columns.keys() and obj._columns[field2]._type in ('many2one', 'one2one'):
63+ obj2 = self.pool.get(obj._columns[field2]._obj)
64+ if not obj2.search(cr, uid,
65+ [('id', '=', field_value[i][field2])]):
66+ continue
67+ elif field2 in obj._inherit_fields.keys() and obj._inherit_fields[field2][2]._type in ('many2one', 'one2one'):
68+ obj2 = self.pool.get(obj._inherit_fields[field2][2]._obj)
69+ if not obj2.search(cr, uid,
70+ [('id', '=', field_value[i][field2])]):
71+ continue
72+ # TODO add test for many2many and one2many
73+ field_value2[i][field2] = field_value[i][field2]
74+ field_value = field_value2
75+ defaults[field] = field_value
76+
77+ # Next method: get the default values defined in the object
78+ defaults_props = [] # will take last-resort values
79+ for f in fields_list:
80+ if f in defaults:
81+ continue
82 if f in self._defaults:
83 if callable(self._defaults[f]):
84 defaults[f] = self._defaults[f](self, cr, uid, context)
85@@ -1158,53 +1211,21 @@
86 defaults[f] = prop_value
87 else:
88 if f not in defaults:
89- defaults[f] = False
90-
91- # get the default values set by the user and override the default
92- # values defined in the object
93- ir_values_obj = self.pool.get('ir.values')
94- res = ir_values_obj.get(cr, uid, 'default', False, [self._name])
95- for id, field, field_value in res:
96- if field in fields_list:
97- fld_def = (field in self._columns) and self._columns[field] or self._inherit_fields[field][2]
98- if fld_def._type in ('many2one', 'one2one'):
99- obj = self.pool.get(fld_def._obj)
100- if not obj.search(cr, uid, [('id', '=', field_value or False)]):
101- continue
102- if fld_def._type in ('many2many'):
103- obj = self.pool.get(fld_def._obj)
104- field_value2 = []
105- for i in range(len(field_value)):
106- if not obj.search(cr, uid, [('id', '=',
107- field_value[i])]):
108- continue
109- field_value2.append(field_value[i])
110- field_value = field_value2
111- if fld_def._type in ('one2many'):
112- obj = self.pool.get(fld_def._obj)
113- field_value2 = []
114- for i in range(len(field_value)):
115- field_value2.append({})
116- for field2 in field_value[i]:
117- if field2 in obj._columns.keys() and obj._columns[field2]._type in ('many2one', 'one2one'):
118- obj2 = self.pool.get(obj._columns[field2]._obj)
119- if not obj2.search(cr, uid,
120- [('id', '=', field_value[i][field2])]):
121- continue
122- elif field2 in obj._inherit_fields.keys() and obj._inherit_fields[field2][2]._type in ('many2one', 'one2one'):
123- obj2 = self.pool.get(obj._inherit_fields[field2][2]._obj)
124- if not obj2.search(cr, uid,
125- [('id', '=', field_value[i][field2])]):
126- continue
127- # TODO add test for many2many and one2many
128- field_value2[i][field2] = field_value[i][field2]
129- field_value = field_value2
130- defaults[field] = field_value
131-
132- # get the default values from the context
133- for key in context or {}:
134- if key.startswith('default_') and (key[8:] in fields_list):
135- defaults[key[8:]] = context[key]
136+ defaults_props[f] = False
137+
138+
139+ remaining_fields = [ f for f in fields_list if f not in defaults ]
140+
141+ if remaining_fields:
142+ # get the default values for the inherited fields
143+ for t in self._inherits.keys():
144+ defaults.update(self.pool.get(t).default_get(cr, uid, remaining_fields,
145+ context))
146+
147+ if defaults_props:
148+ # must be updated after the _inherits.keys() lookup
149+ defaults.update(defaults_props)
150+
151 return defaults
152
153