Reputation: 208
I'm creating a custom module in odoo and I'm struggling with an inheritance issue, let's say i have the following implementation :
class SuperModel(models.Model) :
_name="model_name"
_inherits={'model_name.one':'model_name_one_id',
'model_name.two':'model_name_two_id'}
selection = fields.Selection(selection=[('m1','Model one'),('m2','Model Two')])
model_name_one_id = fields.Many2one(comodel_name="model_name.one",ondelete="cascade")
model_name_two_id = fields.Many2one(comodel_name="model_name.two",ondelete="cascade")
class ModelOne(models.Model):
_name="model_name.one"
value_one = fields.Char()
class ModelTwo(models.Model):
_name="model_name.two"
value_two = fields.Char()
What i want to achieve, is by selecting "Model 1" or "Model 2" in the main model view, only the corresponding fields will be displayed and stored in the database.
But whenever i create a record for "SuperModel" both records are created in "ModelOne" and "ModelTwo" tables.
For example if i select "Model 1" and fill "value_one", when saving, an empty record is created in "Model 2" table (model_name_two_id == False). How can i prevent that ?
Thank you for helping :)
Upvotes: 0
Views: 416
Reputation: 14731
OK using Delegate is impossible in you condition because odoo will make sure that the many2one must have a value or the saving will not happen so use related field like this
class SuperModel(models.Model) :
_name="model_name"
selection = fields.Selection(selection=[('m1','Model one'),('m2','Model Two')])
# indecate that the Many2one are delegated = true
model_name_one_id = fields.Many2one(comodel_name="model_name.one",ondelete="cascade", )
model_name_two_id = fields.Many2one(comodel_name="model_name.two",ondelete="cascade", )
value_one = fields.Char(related="model_name_one_id.value_one")
value_two = fields.Char(related="model_name_two_id.value_two")
@api.model
def create(self, vals):
if not rec_id.value_one:
# if the related field of model_name_one_id are no null
# create a record from that relateds fields add it to vals
# i used vals directly odoo is smart to ignore the non existing field in model_name.one
# or iterate the vals and extract a dictionary of model_name.one
m2on_rec = self.env['model_name.one'].create(vals) # create a record
vals.update({'model_name_one_id':m2on_rec.id}) # add the id to vals
return super(SuperModel, self).create(vals)
elif not rec_id.value_one:
# same thing for the second many2one
else :
# show error or create a simple record
return return super(SuperModel, self).create(vals)
@api.one # is used one so i make sure that self containing only one record it's hard for multi need to much code
def write(self, vals):
# check if any of the related field of model_name_one_id is changed
if any(field_name in self.env['model_name.one'] for field_name in vals.keys()) :
# then check the many2one field all ready have a value so the operation here is update
if self.model_name_one_id:
return super(SuperModel, self).write(vals) # related field will do the changes
else :
# here we need to delete the record of model_name_two_id
self.model_name_two_id.unlink()
# here the same thing in create you need to create the record
retrun super(SuperModel, self).write(vals)
else :
# same thing for model_name_two_id
i tried this solution and it work sooo fine just create the record of the one2many field it's like you are the one who are delegating not the frame work for editing is more complex because you need to delete the record and then save the new one
Upvotes: 1