[MERGE] Sync with trunk

bzr revid: tde@openerp.com-20130624160006-ndlo68bdmm3ndj21
This commit is contained in:
Thibault Delavallée
2013-06-24 18:00:06 +02:00
7 changed files with 79 additions and 42 deletions
-1
View File
@@ -843,7 +843,6 @@ A property is a special field: fields.property.
relation='product.pricelist',
string="Sale Pricelist",
method=True,
view_load=True,
group_name="Pricelists Properties"),
}
-1
View File
@@ -42,7 +42,6 @@ CREATE TABLE ir_model_fields (
field_description varchar(256),
ttype varchar(64),
state varchar(64) default 'base',
view_load boolean,
relate boolean default False,
relation_field varchar(128),
translate boolean default False,
-3
View File
@@ -245,7 +245,6 @@ class ir_model_fields(osv.osv):
"specified as a Python expression defining a list of triplets. "
"For example: [('color','=','red')]"),
'groups': fields.many2many('res.groups', 'ir_model_fields_group_rel', 'field_id', 'group_id', 'Groups'),
'view_load': fields.boolean('View Auto-Load'),
'selectable': fields.boolean('Selectable'),
'modules': fields.function(_in_modules, type='char', size=128, string='In Modules', help='List of modules in which the field is defined'),
'serialization_field_id': fields.many2one('ir.model.fields', 'Serialization Field', domain = "[('ttype','=','serialized')]",
@@ -256,7 +255,6 @@ class ir_model_fields(osv.osv):
}
_rec_name='field_description'
_defaults = {
'view_load': 0,
'selection': "",
'domain': "[]",
'name': 'x_',
@@ -386,7 +384,6 @@ class ir_model_fields(osv.osv):
('size', 'size', int),
('on_delete', 'ondelete', str),
('translate', 'translate', bool),
('view_load', 'view_load', bool),
('selectable', 'selectable', bool),
('select_level', 'select', int),
('selection', 'selection', eval),
+12 -24
View File
@@ -22,7 +22,7 @@
import time
from openerp.osv import osv, fields
from openerp.osv.orm import browse_record
from openerp.osv.orm import browse_record, browse_null
from openerp.tools.misc import attrgetter
# -------------------------------------------------------------------------
@@ -32,27 +32,10 @@ from openerp.tools.misc import attrgetter
class ir_property(osv.osv):
_name = 'ir.property'
def _models_field_get(self, cr, uid, field_key, field_value, context=None):
get = attrgetter(field_key, field_value)
obj = self.pool.get('ir.model.fields')
ids = obj.search(cr, uid, [('view_load','=',1)], context=context)
res = set()
for o in obj.browse(cr, uid, ids, context=context):
res.add(get(o))
return list(res)
def _models_get(self, cr, uid, context=None):
return self._models_field_get(cr, uid, 'model', 'model_id.name', context)
def _models_get2(self, cr, uid, context=None):
return self._models_field_get(cr, uid, 'relation', 'relation', context)
_columns = {
'name': fields.char('Name', size=128, select=1),
'res_id': fields.reference('Resource', selection=_models_get, size=128,
help="If not set, acts as a default value for new resources", select=1),
'res_id': fields.char('Resource', size=128, help="If not set, acts as a default value for new resources", select=1),
'company_id': fields.many2one('res.company', 'Company', select=1),
'fields_id': fields.many2one('ir.model.fields', 'Field', ondelete='cascade', required=True, select=1),
@@ -60,7 +43,7 @@ class ir_property(osv.osv):
'value_integer' : fields.integer('Value'),
'value_text' : fields.text('Value'), # will contain (char, text)
'value_binary' : fields.binary('Value'),
'value_reference': fields.reference('Value', selection=_models_get2, size=128),
'value_reference': fields.char('Value', size=128),
'value_datetime' : fields.datetime('Value'),
'type' : fields.selection([('char', 'Char'),
@@ -72,6 +55,7 @@ class ir_property(osv.osv):
('many2one', 'Many2One'),
('date', 'Date'),
('datetime', 'DateTime'),
('selection', 'Selection'),
],
'Type',
required=True,
@@ -106,6 +90,7 @@ class ir_property(osv.osv):
'many2one': 'value_reference',
'date' : 'value_datetime',
'datetime' : 'value_datetime',
'selection': 'value_text',
}
field = type2field.get(type_)
if not field:
@@ -128,7 +113,6 @@ class ir_property(osv.osv):
values[field] = value
return values
def write(self, cr, uid, ids, values, context=None):
return super(ir_property, self).write(cr, uid, ids, self._update_values(cr, uid, ids, values), context=context)
@@ -136,7 +120,7 @@ class ir_property(osv.osv):
return super(ir_property, self).create(cr, uid, self._update_values(cr, uid, None, values), context=context)
def get_by_record(self, cr, uid, record, context=None):
if record.type in ('char', 'text'):
if record.type in ('char', 'text', 'selection'):
return record.value_text
elif record.type == 'float':
return record.value_float
@@ -147,7 +131,10 @@ class ir_property(osv.osv):
elif record.type == 'binary':
return record.value_binary
elif record.type == 'many2one':
return record.value_reference
if not record.value_reference:
return browse_null()
model, resource_id = record.value_reference.split(',')
return self.pool.get(model).browse(cr, uid, int(resource_id), context=context)
elif record.type == 'datetime':
return record.value_datetime
elif record.type == 'date':
@@ -160,7 +147,8 @@ class ir_property(osv.osv):
domain = self._get_domain(cr, uid, name, model, context=context)
if domain is not None:
domain = [('res_id', '=', res_id)] + domain
nid = self.search(cr, uid, domain, context=context)
#make the search with company_id asc to make sure that properties specific to a company are given first
nid = self.search(cr, uid, domain, limit=1, order='company_id asc', context=context)
if not nid: return False
record = self.browse(cr, uid, nid[0], context=context)
return self.get_by_record(cr, uid, record, context=context)
+10 -7
View File
@@ -109,7 +109,6 @@ 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
@@ -1383,8 +1382,10 @@ class property(function):
def _get_by_id(self, obj, cr, uid, prop_name, ids, context=None):
prop = obj.pool.get('ir.property')
vids = [obj._name + ',' + str(oid) for oid in ids]
domain = [('fields_id.model', '=', obj._name), ('fields_id.name', 'in', prop_name)]
def_id = self._field_get(cr, uid, obj._name, prop_name[0])
company = obj.pool.get('res.company')
cid = company._company_default_get(cr, uid, obj._name, def_id, context=context)
domain = [('fields_id.model', '=', obj._name), ('fields_id.name', 'in', prop_name), ('company_id', '=', cid)]
#domain = prop._get_domain(cr, uid, prop_name, obj._name, context)
if vids:
domain = [('res_id', 'in', vids)] + domain
@@ -1477,11 +1478,13 @@ class property(function):
self.field_id[cr.dbname] = res and res[0]
return self.field_id[cr.dbname]
def __init__(self, obj_prop, **args):
# TODO remove obj_prop parameter (use many2one type)
def __init__(self, **args):
self.field_id = {}
function.__init__(self, self._fnct_read, False, self._fnct_write,
obj_prop, multi='properties', **args)
if 'view_load' in args:
_logger.warning("view_load attribute is deprecated on ir.fields. Args: %r", args)
obj = 'relation' in args and args['relation'] or ''
function.__init__(self, self._fnct_read, False, self._fnct_write, obj=obj, multi='properties', **args)
def restart(self):
self.field_id = {}
+33 -6
View File
@@ -773,7 +773,6 @@ class BaseModel(object):
'field_description': f.string,
'ttype': f._type,
'relation': f._obj or '',
'view_load': (f.view_load and 1) or 0,
'select_level': tools.ustr(f.select or 0),
'readonly': (f.readonly and 1) or 0,
'required': (f.required and 1) or 0,
@@ -803,12 +802,12 @@ class BaseModel(object):
vals['id'] = id
cr.execute("""INSERT INTO ir_model_fields (
id, model_id, model, name, field_description, ttype,
relation,view_load,state,select_level,relation_field, translate, serialization_field_id
relation,state,select_level,relation_field, translate, serialization_field_id
) VALUES (
%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s
%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s
)""", (
id, vals['model_id'], vals['model'], vals['name'], vals['field_description'], vals['ttype'],
vals['relation'], bool(vals['view_load']), 'base',
vals['relation'], 'base',
vals['select_level'], vals['relation_field'], bool(vals['translate']), vals['serialization_field_id']
))
if 'module' in context:
@@ -826,11 +825,11 @@ class BaseModel(object):
cr.commit()
cr.execute("""UPDATE ir_model_fields SET
model_id=%s, field_description=%s, ttype=%s, relation=%s,
view_load=%s, select_level=%s, readonly=%s ,required=%s, selectable=%s, relation_field=%s, translate=%s, serialization_field_id=%s
select_level=%s, readonly=%s ,required=%s, selectable=%s, relation_field=%s, translate=%s, serialization_field_id=%s
WHERE
model=%s AND name=%s""", (
vals['model_id'], vals['field_description'], vals['ttype'],
vals['relation'], bool(vals['view_load']),
vals['relation'],
vals['select_level'], bool(vals['readonly']), bool(vals['required']), bool(vals['selectable']), vals['relation_field'], bool(vals['translate']), vals['serialization_field_id'], vals['model'], vals['name']
))
break
@@ -5288,6 +5287,34 @@ class BaseModel(object):
# for backward compatibility
resolve_o2m_commands_to_record_dicts = resolve_2many_commands
def search_read(self, cr, uid, domain=None, fields=None, offset=0, limit=None, order=None, context=None):
"""
Performs a ``search()`` followed by a ``read()``.
:param cr: database cursor
:param user: current user id
:param domain: Search domain, see ``args`` parameter in ``search()``. Defaults to an empty domain that will match all records.
:param fields: List of fields to read, see ``fields`` parameter in ``read()``. Defaults to all fields.
:param offset: Number of records to skip, see ``offset`` parameter in ``search()``. Defaults to 0.
:param limit: Maximum number of records to return, see ``limit`` parameter in ``search()``. Defaults to no limit.
:param order: Columns to sort result, see ``order`` parameter in ``search()``. Defaults to no sort.
:param context: context arguments.
:return: List of dictionaries containing the asked fields.
:rtype: List of dictionaries.
"""
record_ids = self.search(cr, uid, domain or [], offset, limit or False, order or False, context or {})
if not record_ids:
return []
result = self.read(cr, uid, record_ids, fields or [], context or {})
# reorder read
if len(result) >= 1:
index = {}
for r in result:
index[r['id']] = r
result = [index[x] for x in record_ids if x in index]
return result
def _register_hook(self, cr):
""" stuff to do right after the registry is built """
pass
+24
View File
@@ -76,6 +76,30 @@ class TestORM(common.TransactionCase):
with self.assertRaises(Exception):
self.partner.unlink(cr, uid2, [p1,p2])
@mute_logger('openerp.osv.orm')
def test_search_read(self):
# simple search_read
self.partner.create(self.cr, UID, {'name': 'MyPartner1'})
found = self.partner.search_read(self.cr, UID, [['name', '=', 'MyPartner1']], ['name'])
self.assertEqual(len(found), 1)
self.assertEqual(found[0]['name'], 'MyPartner1')
self.assertTrue('id' in found[0])
# search_read correct order
self.partner.create(self.cr, UID, {'name': 'MyPartner2'})
found = self.partner.search_read(self.cr, UID, [['name', 'like', 'MyPartner']], ['name'], order="name")
self.assertEqual(len(found), 2)
self.assertEqual(found[0]['name'], 'MyPartner1')
self.assertEqual(found[1]['name'], 'MyPartner2')
found = self.partner.search_read(self.cr, UID, [['name', 'like', 'MyPartner']], ['name'], order="name desc")
self.assertEqual(len(found), 2)
self.assertEqual(found[0]['name'], 'MyPartner2')
self.assertEqual(found[1]['name'], 'MyPartner1')
# search_read that finds nothing
found = self.partner.search_read(self.cr, UID, [['name', '=', 'Does not exists']], ['name'])
self.assertEqual(len(found), 0)
class TestInherits(common.TransactionCase):
""" test the behavior of the orm for models that use _inherits;