The res.config.settings
model is transient and is not saved to the database. Any fields you define on this model must be saved to the database somewhere explicitly. There are a few options.
- The website module (Option #1)
- The account module (Option #2)
- The CRM module (Option #3)
res.config.setting
source
Use the related=xxx
field option and a singleton model.
With this method, fields on res.config.settings
will be saved to the singleton model. The values are then available on the singleton model. You can see this method in-action in the website module, where the website
model stores settings from res.config.settings
(link here).
- These settings can be company-wide, or database-wide.
- Values are saved in the
my_singleton
table in PostgreSQL.
from odoo import models, fields, api
class MySingleton(models.Model):
_name = 'my.singleton'
company_id = fields.Many2one(comodel_name='res.company')
# define a field on our 'singleton' model
my_setting = fields.Char()
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
def _default_my_singleton(self):
# get the singleton instance. note that `company_id` is used in the search
# domain to ensure the correct record is returned in multi-company environments
# if the model is not multi-company-aware, you can use a blank domain
return self.env['my.singleton'].search([('company_id', '=', self.env.company.id)], limit=1)
# make sure a reference to the singleton is available
my_singleton_id = fields.Many2one(comodel_name='my.singleton', default=_default_my_singleton)
# use `related=xxx` to link back to the singleton models' field
my_setting = fields.Char(related='my_singleton_id.my_setting')
As an alternative to #1, the res.company
model can be used instead of a singleton.
- These settings are company-wide (i.e. they are company-aware).
- Values are saved in the
res_company
table in PostgreSQL.
from odoo import models, fields, api
class ResCompany(models.Model):
_inherit = 'res.company'
my_setting = fields.Boolean(string='My Setting')
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
# company_id is already set on the res.config.settings model, and will point to
# the currently active company
my_setting = fields.Boolean(related='company_id.my_setting')
Use ir.config_parameter
to save configuration settings.
While this method is more terse, the ir.config_parameter
model only accepts strings, so any non-string values will need to be parsed before being consumed.
- These settings are database-wide (i.e. not company-aware).
- Values are saved in the
ir_config_parameter
table in PostgreSQL.
Note: It is possible to read fields (where config_parameter
is set) directly from a res.config.settings
record. However, that method requires instantiating a full config settings object (which might have hundres of fields, and take seconds to load). The method outlined below is much faster.
from odoo import models, fields, api
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
my_char = fields.Char(config_parameter='my_module.my_string')
my_bool = fields.Boolean(config_parameter='my_module.my_bool')
my_float = fields.Float(config_parameter='my_module.my_float', digits=(7,4))
my_m2o = fields.Many2one(config_parameter='my_module.my_m2o')
my_o2m = fields.One2many(config_parameter='my_module.my_o2m')
Then, to get a copy of the setting:
def some_function(self):
# only uid=1 has access to ir.config_parameter, so we need sudo()
get_param = self.env['ir.config_parameter'].sudo().get_param
# basic fields are fairly easy to parse. adding a try/except block
# and catching ValueError() exceptions would be good practice
my_char = get_param('my_module.my_string')
my_bool = bool(get_param('my_module.my_bool'))
my_float = float(get_param('my_module.my_float'))
# x2x examples coming soon
Handy! Thanks dude :)