官网下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')