# -*- coding: utf-8 -*- import logging from openerp.osv import orm, fields from openerp.tools.translate import _ from openerp.addons.base.ir.ir_model import MODULE_UNINSTALL_FLAG class IrModel(orm.Model): _inherit = 'ir.model' def _drop_table(self, cr, uid, ids, context=None): # Allow to skip this step during model unlink # The super method crashes if the model cannot be instantiated if context and context.get('no_drop_table'): return True return super(IrModel, self)._drop_table(cr, uid, ids, context=context) class CleanupPurgeLineModel(orm.TransientModel): _inherit = 'cleanup.purge.line' _name = 'cleanup.purge.line.model' _columns = { 'wizard_id': fields.many2one( 'cleanup.purge.wizard.model', 'Purge Wizard', readonly=True), } def purge(self, cr, uid, ids, context=None): """ Unlink models upon manual confirmation. """ model_pool = self.pool['ir.model'] attachment_pool = self.pool['ir.attachment'] constraint_pool = self.pool['ir.model.constraint'] local_context=(context or {}).copy() local_context.update({ MODULE_UNINSTALL_FLAG: True, 'no_drop_table': True, }) for line in self.browse(cr, uid, ids, context=context): cr.execute( "SELECT id, model from ir_model WHERE model = %s", (line.name,)) row = cr.fetchone() if row: self.logger.info('Purging model %s', row[1]) attachment_ids = attachment_pool.search( cr, uid, [('res_model', '=', line.name)], context=context) if attachment_ids: attachment_pool.write( cr, uid, attachment_ids, {'res_model': False}, context=context) constraint_ids = constraint_pool.search( cr, uid, [('model', '=', line.name)], context=context) if constraint_ids: constraint_pool.unlink( cr, uid, constraint_ids, context=context) model_pool.unlink(cr, uid, [row[0]], context=local_context) line.write({'purged': True}) cr.commit() return True class CleanupPurgeWizardModel(orm.TransientModel): _inherit = 'cleanup.purge.wizard' _name = 'cleanup.purge.wizard.model' def default_get(self, cr, uid, fields, context=None): res = super(CleanupPurgeWizardModel, self).default_get( cr, uid, fields, context=context) if 'name' in fields: res['name'] = _('Purge models') return res def find(self, cr, uid, context=None): """ Search for models that cannot be instantiated. """ res = [] cr.execute("SELECT model from ir_model") for (model,) in cr.fetchall(): if not self.pool.get(model): res.append((0, 0, {'name': model})) if not res: raise orm.except_orm( _('Nothing to do'), _('No orphaned models found')) return res _columns = { 'purge_line_ids': fields.one2many( 'cleanup.purge.line.model', 'wizard_id', 'Models to purge'), }