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
=== modified file 'openerp/osv/orm.py'
--- openerp/osv/orm.py 2011-05-27 12:32:36 +0000
+++ openerp/osv/orm.py 2011-06-10 09:31:58 +0000
@@ -1122,6 +1122,8 @@
1122 contents. This can also be selectively overriden by passing a field-specific flag1122 contents. This can also be selectively overriden by passing a field-specific flag
1123 in the form ``bin_size_XXX: True/False`` where ``XXX`` is the name of the field.1123 in the form ``bin_size_XXX: True/False`` where ``XXX`` is the name of the field.
1124 Note: The ``bin_size_XXX`` form is new in OpenERP v6.0.1124 Note: The ``bin_size_XXX`` form is new in OpenERP v6.0.
1125 If the ``__ignore_ir_values`` is passed and is positive,
1126 defaults will NOT be looked up in ir.values
1125 :return: dictionary of the default values (set on the object model class, through user preferences, or in the context)1127 :return: dictionary of the default values (set on the object model class, through user preferences, or in the context)
1126 """1128 """
1127 # trigger view init hook1129 # trigger view init hook
@@ -1131,13 +1133,64 @@
1131 context = {}1133 context = {}
1132 defaults = {}1134 defaults = {}
11331135
1134 # get the default values for the inherited fields1136 # Most significant: get the default values from the context
1135 for t in self._inherits.keys():1137 for f in fields_list:
1136 defaults.update(self.pool.get(t).default_get(cr, uid, fields_list,1138 if ('default_' + f) in context:
1137 context))1139 defaults[f] = context['default_' + f]
11381140
1139 # get the default values defined in the object1141 # Next significant:
1140 for f in fields_list:1142 # get the default values set by the user and override the default
1143 # values defined in the object
1144 ir_values_obj = self.pool.get('ir.values')
1145 if context.get('__ignore_ir_values', False):
1146 res = []
1147 else:
1148 res = ir_values_obj.get(cr, uid, 'default', False, [self._name])
1149
1150 for id, field, field_value in res:
1151 if field in defaults or (field not in fields_list):
1152 continue
1153
1154 fld_def = (field in self._columns) and self._columns[field] or self._inherit_fields[field][2]
1155 if fld_def._type in ('many2one', 'one2one'):
1156 obj = self.pool.get(fld_def._obj)
1157 if not obj.search(cr, uid, [('id', '=', field_value or False)]):
1158 continue
1159 if fld_def._type in ('many2many'):
1160 obj = self.pool.get(fld_def._obj)
1161 field_value2 = []
1162 for i in range(len(field_value)):
1163 if not obj.search(cr, uid, [('id', '=',
1164 field_value[i])]):
1165 continue
1166 field_value2.append(field_value[i])
1167 field_value = field_value2
1168 if fld_def._type in ('one2many'):
1169 obj = self.pool.get(fld_def._obj)
1170 field_value2 = []
1171 for i in range(len(field_value)):
1172 field_value2.append({})
1173 for field2 in field_value[i]:
1174 if field2 in obj._columns.keys() and obj._columns[field2]._type in ('many2one', 'one2one'):
1175 obj2 = self.pool.get(obj._columns[field2]._obj)
1176 if not obj2.search(cr, uid,
1177 [('id', '=', field_value[i][field2])]):
1178 continue
1179 elif field2 in obj._inherit_fields.keys() and obj._inherit_fields[field2][2]._type in ('many2one', 'one2one'):
1180 obj2 = self.pool.get(obj._inherit_fields[field2][2]._obj)
1181 if not obj2.search(cr, uid,
1182 [('id', '=', field_value[i][field2])]):
1183 continue
1184 # TODO add test for many2many and one2many
1185 field_value2[i][field2] = field_value[i][field2]
1186 field_value = field_value2
1187 defaults[field] = field_value
1188
1189 # Next method: get the default values defined in the object
1190 defaults_props = [] # will take last-resort values
1191 for f in fields_list:
1192 if f in defaults:
1193 continue
1141 if f in self._defaults:1194 if f in self._defaults:
1142 if callable(self._defaults[f]):1195 if callable(self._defaults[f]):
1143 defaults[f] = self._defaults[f](self, cr, uid, context)1196 defaults[f] = self._defaults[f](self, cr, uid, context)
@@ -1158,53 +1211,21 @@
1158 defaults[f] = prop_value1211 defaults[f] = prop_value
1159 else:1212 else:
1160 if f not in defaults:1213 if f not in defaults:
1161 defaults[f] = False1214 defaults_props[f] = False
11621215
1163 # get the default values set by the user and override the default1216
1164 # values defined in the object1217 remaining_fields = [ f for f in fields_list if f not in defaults ]
1165 ir_values_obj = self.pool.get('ir.values')1218
1166 res = ir_values_obj.get(cr, uid, 'default', False, [self._name])1219 if remaining_fields:
1167 for id, field, field_value in res:1220 # get the default values for the inherited fields
1168 if field in fields_list:1221 for t in self._inherits.keys():
1169 fld_def = (field in self._columns) and self._columns[field] or self._inherit_fields[field][2]1222 defaults.update(self.pool.get(t).default_get(cr, uid, remaining_fields,
1170 if fld_def._type in ('many2one', 'one2one'):1223 context))
1171 obj = self.pool.get(fld_def._obj)1224
1172 if not obj.search(cr, uid, [('id', '=', field_value or False)]):1225 if defaults_props:
1173 continue1226 # must be updated after the _inherits.keys() lookup
1174 if fld_def._type in ('many2many'):1227 defaults.update(defaults_props)
1175 obj = self.pool.get(fld_def._obj)1228
1176 field_value2 = []
1177 for i in range(len(field_value)):
1178 if not obj.search(cr, uid, [('id', '=',
1179 field_value[i])]):
1180 continue
1181 field_value2.append(field_value[i])
1182 field_value = field_value2
1183 if fld_def._type in ('one2many'):
1184 obj = self.pool.get(fld_def._obj)
1185 field_value2 = []
1186 for i in range(len(field_value)):
1187 field_value2.append({})
1188 for field2 in field_value[i]:
1189 if field2 in obj._columns.keys() and obj._columns[field2]._type in ('many2one', 'one2one'):
1190 obj2 = self.pool.get(obj._columns[field2]._obj)
1191 if not obj2.search(cr, uid,
1192 [('id', '=', field_value[i][field2])]):
1193 continue
1194 elif field2 in obj._inherit_fields.keys() and obj._inherit_fields[field2][2]._type in ('many2one', 'one2one'):
1195 obj2 = self.pool.get(obj._inherit_fields[field2][2]._obj)
1196 if not obj2.search(cr, uid,
1197 [('id', '=', field_value[i][field2])]):
1198 continue
1199 # TODO add test for many2many and one2many
1200 field_value2[i][field2] = field_value[i][field2]
1201 field_value = field_value2
1202 defaults[field] = field_value
1203
1204 # get the default values from the context
1205 for key in context or {}:
1206 if key.startswith('default_') and (key[8:] in fields_list):
1207 defaults[key[8:]] = context[key]
1208 return defaults1229 return defaults
12091230
12101231