odoo12 ResConfigSettings 源码分析 一

官网下res.config.settings。。使用的都很模糊。无非都是 

default_foo = fields.type(..., default_model='my.model')
group_bar = fields.Boolean(..., group='base.group_user', implied_group='my.group')
module_baz = fields.Boolean(...)
other_field = fields.type(...)

作为开发者,肯定 就只能分析源码了。。这些用法到底是什么?

发现关键源码为两部分

    @api.model
    def default_get(self, fields):
        IrDefault = self.env['ir.default']
        IrConfigParameter = self.env['ir.config_parameter'].sudo()
        classified = self._get_classified_fields()

        res = super(ResConfigSettings, self).default_get(fields)

        # defaults: take the corresponding default value they set
        for name, model, field in classified['default']:
            # 根据 model 和 filed  取出json_value
            value = IrDefault.get(model, field)
            if value is not None:
                res[name] = value

        # groups: which groups are implied by the group Employee
        for name, groups, implied_group in classified['group']:
            res[name] = all(implied_group in group.implied_ids for group in groups)
            if self._fields[name].type == 'selection':
                res[name] = int(res[name])

        # modules: which modules are installed/to install
        for name, module in classified['module']:
            res[name] = module.state in ('installed', 'to install', 'to upgrade')
            if self._fields[name].type == 'selection':
                res[name] = int(res[name])

        # config: get & convert stored ir.config_parameter (or default)
        WARNING_MESSAGE = "Error when converting value %r of field %s for ir.config.parameter %r"
        for name, icp in classified['config']:
            field = self._fields[name]
            value = IrConfigParameter.get_param(icp, field.default(self) if field.default else False)
            if value is not False:
                if field.type == 'many2one':
                    try:
                        # Special case when value is the id of a deleted record, we do not want to
                        # block the settings screen
                        value = self.env[field.comodel_name].browse(int(value)).exists().id
                    except ValueError:
                        _logger.warning(WARNING_MESSAGE, value, field, icp)
                        value = False
                elif field.type == 'integer':
                    try:
                        value = int(value)
                    except ValueError:
                        _logger.warning(WARNING_MESSAGE, value, field, icp)
                        value = 0
                elif field.type == 'float':
                    try:
                        value = float(value)
                    except ValueError:
                        _logger.warning(WARNING_MESSAGE, value, field, icp)
                        value = 0.0
                elif field.type == 'boolean':
                    value = bool(value)
            res[name] = value

        # other fields: call the method 'get_values'
        # The other methods that start with `get_default_` are deprecated
        for method in dir(self):
            if method.startswith('get_default_'):
                _logger.warning(_('Methods that start with `get_default_` are deprecated. Override `get_values` instead(Method %s)') % method)
        res.update(self.get_values())

        return res

加载config 的所有字段。里面最关键的代码段又在

    @api.model
    def _get_classified_fields(self):
        """ return a dictionary with the fields classified by category::

                {   'default': [('default_foo', 'model', 'foo'), ...],
                    'group':   [('group_bar', [browse_group], browse_implied_group), ...],
                    'module':  [('module_baz', browse_module), ...],
                    'config':  [('config_qux', 'my.parameter'), ...],
                    'other':   ['other_field', ...],
                }
        """
        IrModule = self.env['ir.module.module']
        Groups = self.env['res.groups']
        ref = self.env.ref

        defaults, groups, modules, configs, others = [], [], [], [], []
        #self._fields 保存了当前类的所有field 属性
        for name, field in self._fields.items():
            if name.startswith('default_'):
                if not hasattr(field, 'default_model'):
                    raise Exception("Field %s without attribute 'default_model'" % field)
                defaults.append((name, field.default_model, name[8:]))
            elif name.startswith('group_'):
                if field.type not in ('boolean', 'selection'):
                    raise Exception("Field %s must have type 'boolean' or 'selection'" % field)
                if not hasattr(field, 'implied_group'):
                    raise Exception("Field %s without attribute 'implied_group'" % field)
                # 获取 模块的field 当前的group 属性组。如果没有,则为base.group_user
                field_group_xmlids = getattr(field, 'group', 'base.group_user').split(',')
                #得到所有属性组
                field_groups = Groups.concat(*(ref(it) for it in field_group_xmlids))
                #ref(field.implied_group)  为 field 的implied_group 的id
                groups.append((name, field_groups, ref(field.implied_group)))
            elif name.startswith('module_'):
                if field.type not in ('boolean', 'selection'):
                    raise Exception("Field %s must have type 'boolean' or 'selection'" % field)
                module = IrModule.sudo().search([('name', '=', name[7:])], limit=1)
                modules.append((name, module))
            elif hasattr(field, 'config_parameter'):
                if field.type not in ('boolean', 'integer', 'float', 'char', 'selection', 'many2one'):
                    raise Exception("Field %s must have type 'boolean', 'integer', 'float', 'char', 'selection' or 'many2one'" % field)
                configs.append((name, field.config_parameter))
            else:
                others.append(name)

        return {'default': defaults, 'group': groups, 'module': modules, 'config': configs, 'other': others}

可以看到

字段分为 default group modules configs 和 other 分别做了处理

看段demo然后分别分析

class ConfigSettings(models.TransientModel):
    _inherit = 'res.config.settings'
    # zhy_id = fields.Many2one('zhy.sale', string="zhy_sale",
    #                             ondelete='cascade')    
    # 默认会存到数据库 其key为config_parameter的值(上例中为:my.parameter), value为本配置字段的值
    config_name_edit = fields.Boolean(config_parameter='zhy.name_edit')
    #这样就会自动存到 ir.default 中。mode 为 'zhy.sale',字段为 pr_unit
    default_pr_unit = fields.Float(default_model='zhy.sale')
    #bool一样。这里用 Selection 主要看效果
    group_active = fields.Boolean(group='base.group_user',implied_group='zhy.group_zhy_active')

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值