Odoo 中的嵌入式模型存储(继承)
Embedded models storage in Odoo (Inherits)
我正在 odoo 中创建一个自定义模块,我正在努力解决继承问题,假设我有以下实现:
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()
我想实现的是,在主模型视图中selecting "Model 1"或"Model 2",只有相应的字段才会显示并存储在数据库中。
但是每当我为 "SuperModel" 创建一条记录时,两条记录都会在 "ModelOne" 和 "ModelTwo" table 中创建。
例如,如果我select "Model 1"和填充"value_one",保存时,在"Model 2" table中创建一个空记录(model_name_two_id == 假)。我怎样才能防止这种情况发生?
感谢您的帮助:)
OK 在你的情况下使用 Delegate 是不可能的,因为 odoo 会确保
many2one 必须有一个值,否则保存不会发生,所以使用这样的相关字段
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
我试过这个解决方案,它工作得很好只需创建 one2many 字段的记录就好像你是委托人而不是编辑框架工作更复杂,因为你需要删除记录然后保存新的
我正在 odoo 中创建一个自定义模块,我正在努力解决继承问题,假设我有以下实现:
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()
我想实现的是,在主模型视图中selecting "Model 1"或"Model 2",只有相应的字段才会显示并存储在数据库中。
但是每当我为 "SuperModel" 创建一条记录时,两条记录都会在 "ModelOne" 和 "ModelTwo" table 中创建。
例如,如果我select "Model 1"和填充"value_one",保存时,在"Model 2" table中创建一个空记录(model_name_two_id == 假)。我怎样才能防止这种情况发生?
感谢您的帮助:)
OK 在你的情况下使用 Delegate 是不可能的,因为 odoo 会确保 many2one 必须有一个值,否则保存不会发生,所以使用这样的相关字段
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
我试过这个解决方案,它工作得很好只需创建 one2many 字段的记录就好像你是委托人而不是编辑框架工作更复杂,因为你需要删除记录然后保存新的