[IMP] ir_model: enable the creation of transient custom models
Rename the field 'osv_memory' on 'ir.model' into 'transient', and make it a regular field instead of a computed one. When instantiating a custom model, use its value to make transient models. This commit alone will make your server crash on an existing database. A small database migration is needed: simply add a boolean column `transient` (with default value false) in table `ir_model`.
This commit is contained in:
committed by
Raphael Collet
parent
b8527edcd2
commit
5c0bfaafd1
@@ -19,6 +19,7 @@ CREATE TABLE ir_model (
|
||||
name varchar,
|
||||
state varchar,
|
||||
info text,
|
||||
transient boolean,
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
|
||||
@@ -57,27 +57,6 @@ class ir_model(osv.osv):
|
||||
_description = "Models"
|
||||
_order = 'model'
|
||||
|
||||
def _is_osv_memory(self, cr, uid, ids, field_name, arg, context=None):
|
||||
models = self.browse(cr, uid, ids, context=context)
|
||||
res = dict.fromkeys(ids)
|
||||
for model in models:
|
||||
if model.model in self.pool:
|
||||
res[model.id] = self.pool[model.model].is_transient()
|
||||
else:
|
||||
_logger.error('Missing model %s' % (model.model, ))
|
||||
return res
|
||||
|
||||
def _search_osv_memory(self, cr, uid, model, name, domain, context=None):
|
||||
if not domain:
|
||||
return []
|
||||
__, operator, value = domain[0]
|
||||
if operator not in ['=', '!=']:
|
||||
raise UserError(_("Invalid Search Criteria") + ": " + _("The osv_memory field can only be compared with = and != operator."))
|
||||
value = bool(value) if operator == '=' else not bool(value)
|
||||
all_model_ids = self.search(cr, uid, [], context=context)
|
||||
is_osv_mem = self._is_osv_memory(cr, uid, all_model_ids, 'osv_memory', arg=None, context=context)
|
||||
return [('id', 'in', [id for id in is_osv_mem if bool(is_osv_mem[id]) == value])]
|
||||
|
||||
def _view_ids(self, cr, uid, ids, field_name, arg, context=None):
|
||||
models = self.browse(cr, uid, ids)
|
||||
res = {}
|
||||
@@ -103,9 +82,7 @@ class ir_model(osv.osv):
|
||||
help="The list of models that extends the current model."),
|
||||
'state': fields.selection([('manual','Custom Object'),('base','Base Object')],'Type', readonly=True),
|
||||
'access_ids': fields.one2many('ir.model.access', 'model_id', 'Access'),
|
||||
'osv_memory': fields.function(_is_osv_memory, string='Transient Model', type='boolean',
|
||||
fnct_search=_search_osv_memory,
|
||||
help="This field specifies whether the model is transient or not (i.e. if records are automatically deleted from the database or not)"),
|
||||
'transient': fields.boolean(string="Transient Model"),
|
||||
'modules': fields.function(_in_modules, type='char', string='In Modules', help='List of modules in which the object is defined or inherited'),
|
||||
'view_ids': fields.function(_view_ids, type='one2many', obj='ir.ui.view', string='Views'),
|
||||
}
|
||||
@@ -195,7 +172,7 @@ class ir_model(osv.osv):
|
||||
res = super(ir_model,self).create(cr, user, vals, context)
|
||||
if vals.get('state','base')=='manual':
|
||||
# add model in registry
|
||||
self.instanciate(cr, user, vals['model'], context)
|
||||
self.instanciate(cr, user, vals['model'], vals.get('transient', False), context)
|
||||
self.pool.setup_models(cr, partial=(not self.pool.ready))
|
||||
# update database schema
|
||||
model = self.pool[vals['model']]
|
||||
@@ -209,7 +186,7 @@ class ir_model(osv.osv):
|
||||
RegistryManager.signal_registry_change(cr.dbname)
|
||||
return res
|
||||
|
||||
def instanciate(self, cr, user, model, context=None):
|
||||
def instanciate(self, cr, user, model, transient, context=None):
|
||||
if isinstance(model, unicode):
|
||||
model = model.encode('utf-8')
|
||||
|
||||
@@ -217,6 +194,7 @@ class ir_model(osv.osv):
|
||||
_name = model
|
||||
_module = False
|
||||
_custom = True
|
||||
_transient = bool(transient)
|
||||
|
||||
CustomModel._build_model(self.pool, cr)
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="model"/>
|
||||
<field name="osv_memory"/>
|
||||
<field name="transient"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="state"/>
|
||||
@@ -116,7 +116,7 @@
|
||||
<field name="model"/>
|
||||
<field name="name"/>
|
||||
<field name="state"/>
|
||||
<field name="osv_memory"/>
|
||||
<field name="transient"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -126,8 +126,8 @@
|
||||
<search string="Model Description">
|
||||
<field name="name" filter_domain="['|', ('name','ilike',self), ('model','ilike',self)]" string="Model"/>
|
||||
<filter icon="terp-camera_test"
|
||||
string="In Memory"
|
||||
domain="[('osv_memory', '=', True)]"/>
|
||||
string="Transient"
|
||||
domain="[('transient', '=', True)]"/>
|
||||
<separator/>
|
||||
<filter icon="terp-stock_align_left_24"
|
||||
string="Custom"
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
</td>
|
||||
<td colspan="8">
|
||||
<p>Type: <span t-field="o.state"/></p>
|
||||
<p t-if="o.osv_memory">In-memory: True</p>
|
||||
<p t-if="not o.osv_memory">In-memory: False</p>
|
||||
<p t-if="o.transient">Transient: True</p>
|
||||
<p t-if="not o.transient">Transient: False</p>
|
||||
<p>Modules: <span t-field="o.modules"/></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
+2
-1
@@ -353,7 +353,8 @@ class BaseModel(object):
|
||||
if not cr.rowcount:
|
||||
cr.execute('SELECT nextval(%s)', ('ir_model_id_seq',))
|
||||
model_id = cr.fetchone()[0]
|
||||
cr.execute("INSERT INTO ir_model (id,model, name, info,state) VALUES (%s, %s, %s, %s, %s)", (model_id, self._name, self._description, self.__doc__, 'base'))
|
||||
cr.execute("INSERT INTO ir_model (id, model, name, info, state, transient) VALUES (%s, %s, %s, %s, %s, %s)",
|
||||
(model_id, self._name, self._description, self.__doc__, 'base', self._transient))
|
||||
else:
|
||||
model_id = cr.fetchone()[0]
|
||||
if 'module' in context:
|
||||
|
||||
@@ -159,9 +159,9 @@ class Registry(Mapping):
|
||||
|
||||
# load custom models
|
||||
ir_model = self['ir.model']
|
||||
cr.execute('select model from ir_model where state=%s', ('manual',))
|
||||
for (model_name,) in cr.fetchall():
|
||||
ir_model.instanciate(cr, SUPERUSER_ID, model_name, {})
|
||||
cr.execute('select model, transient from ir_model where state=%s', ('manual',))
|
||||
for (model_name, transient) in cr.fetchall():
|
||||
ir_model.instanciate(cr, SUPERUSER_ID, model_name, transient, {})
|
||||
|
||||
# prepare the setup on all models
|
||||
for model in self.models.itervalues():
|
||||
|
||||
Reference in New Issue
Block a user