Skip to content

Instantly share code, notes, and snippets.

@ryanc-me
Last active October 6, 2025 07:55
Show Gist options
  • Select an option

  • Save ryanc-me/a0e35fb6741d73c39f9e3968eaa485ee to your computer and use it in GitHub Desktop.

Select an option

Save ryanc-me/a0e35fb6741d73c39f9e3968eaa485ee to your computer and use it in GitHub Desktop.

Revisions

  1. ryanc-me revised this gist Jun 2, 2022. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions using_res_config_settings.md
    Original file line number Diff line number Diff line change
    @@ -8,7 +8,7 @@ The `res.config.settings` model is transient and is not saved to the database. A
    * [The *website* module (Option #1)](https://github.com/odoo/odoo/blob/14.0/addons/website/models/res_config_settings.py#L14)
    * [The *account* module (Option #2)](https://github.com/odoo/odoo/blob/14.0/addons/account/models/res_config_settings.py#L11)
    * [The *CRM* module (Option #3)](https://github.com/odoo/odoo/blob/14.0/addons/crm/models/res_config_settings.py#L24)
    * [`res.config.settinga` source](https://github.com/odoo/odoo/blob/14.0/odoo/addons/base/models/res_config.py#L328)
    * [`res.config.setting` source](https://github.com/odoo/odoo/blob/14.0/odoo/addons/base/models/res_config.py#L328)



    @@ -55,7 +55,7 @@ class ResConfigSettings(models.TransientModel):

    <br />

    ### OPTION #2
    ### Option #2

    As an alternative to #1, the `res.company` model can be used instead of a singleton.

    @@ -83,7 +83,7 @@ class ResConfigSettings(models.TransientModel):

    <br />

    ### OPTION #3
    ### Option #3

    Use `ir.config_parameter` to save configuration settings.

  2. ryanc-me created this gist Feb 16, 2021.
    124 changes: 124 additions & 0 deletions using_res_config_settings.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,124 @@
    # Using `res.config.settings` in Odoo

    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.

    <br />

    ### References
    * [The *website* module (Option #1)](https://github.com/odoo/odoo/blob/14.0/addons/website/models/res_config_settings.py#L14)
    * [The *account* module (Option #2)](https://github.com/odoo/odoo/blob/14.0/addons/account/models/res_config_settings.py#L11)
    * [The *CRM* module (Option #3)](https://github.com/odoo/odoo/blob/14.0/addons/crm/models/res_config_settings.py#L24)
    * [`res.config.settinga` source](https://github.com/odoo/odoo/blob/14.0/odoo/addons/base/models/res_config.py#L328)



    <br />

    ### Option #1

    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](https://github.com/odoo/odoo/blob/14.0/addons/website/models/res_config_settings.py#L14)).

    * These settings can be company-wide, or database-wide.
    * Values are saved in the `my_singleton` table in PostgreSQL.

    ```python
    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')

    ```

    <br />

    ### OPTION #2

    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.

    ```python
    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')
    ```

    <br />

    ### OPTION #3

    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.

    ```python
    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:
    ```python
    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

    ```