如何在 Python 中使用多级字典创建 Odoo 记录
Posted
技术标签:
【中文标题】如何在 Python 中使用多级字典创建 Odoo 记录【英文标题】:How to create Odoo records with multilevel dictionaries in Python 【发布时间】:2021-12-22 11:47:25 【问题描述】:我正在努力创建一种递归方法来自动在 Odoo 中创建记录。 我请求 SOAP 服务的 WSDL 并对其进行处理,直到收到以下字符串:
'notificaCertificadoRevocado':
'input':
'SolicitudNotificaRevocado':
'optional': False,
'type':
'certificado':
'optional': False,
'type': 'String(value)'
,
'codigoAmbiente':
'optional': False,
'type': 'Int(value)'
这本词典有 1 个父参数“SolicitudNotificaRevocado”和 2 个子参数“certificado”和“codigoAmbiente”。
目前我的 python 方法如下所示:
def _prepare_parameter_list(self, parameter_dict, recursive_data=False):
building_data = recursive_data if recursive_data else
parameter_list = []
for key, value in parameter_dict.items():
if key != 'optional' and key != 'type':
# Create parameters
parameter_name_dict =
'name': key,
'description': ' '.join(word.capitalize() for word in camel_case_split(key)),
characterization_dict = self._prepare_parameter_list(value)
built_parameter_dict = **parameter_name_dict, **characterization_dict
parameter_list.append((0, 0, built_parameter_dict))
# TODO: Here the code stops
return parameter_list
else:
if key == 'optional':
building_data = **building_data, **'optional': value
if key == 'type':
if isinstance(value, dict):
building_data = **building_data, **'parameter_ids': self._prepare_parameter_list(value)
else:
building_data = **building_data, **'type': value.split('(')[0]
return building_data
这很好用,只有一个问题,返回的数据具有以下形式:
[(0, 0,
'name': 'SolicitudOperacionesCuis',
'description': 'Solicitud Operaciones Cuis',
'optional': False,
'parameter_ids': [
(0, 0,
'name': 'codigoAmbiente',
'description': 'Codigo Ambiente',
'optional': False,
'type': 'Int')]
)
]
问题是处理其中一个子参数后的方法由于“返回参数列表”部分而停止。 (我什至在问题部分添加了 TODO 注释) 我想检索以下数据:
[(0, 0,
'name': 'SolicitudOperacionesCuis',
'description': 'Solicitud Operaciones Cuis',
'optional': False,
'parameter_ids': [
(0, 0,
'name': 'certificado',
'description': 'Certificado',
'optional': False,
'type': 'String')]
),
(0, 0,
'name': 'codigoAmbiente',
'description': 'Codigo Ambiente',
'optional': False,
'type': 'Int')]
)
]
我应该如何调整我的方法来实现这一点? 使用递归方法很难!
【问题讨论】:
在您的预期输出中,parameter_ids 是否应该是两次相同数据的列表。还是输入数据有更多选项可供选择? 对不起,我犯了一个错误,我用预期的输出纠正了 从您在递归调用发生的characterization_dict = self._prepare_parameter_list(value)
中的命名来看,您似乎在期待一本字典,但在 TODO 之后您的 return
正在返回一个列表。应该这样吗?
我知道,这篇文章是关于调整我方法的那一部分。不让这个工作的部分。
【参考方案1】:
如果输入数据是已知的,并且有用的数据似乎是输入字典中的数据,那么您不需要递归元素。 更新了下面的类似函数,输出您的预期输出
def _prepare_parameter_list(parameter_dict):
def _return_data_type(value_type):
if value_type == 'Int':
value_type = 'int'
elif value_type == 'String':
value_type = 'str'
elif value_type == 'Long':
value_type = 'float'
return value_type
parent = parameter_dict.get('notificaCertificadoRevocado')
building_data = []
if parent and parent.get('input'):
for key, value in parent['input']:
vals =
'name': key,
'description': ' '.join(word.capitalize() for word in camel_case_split(key)),
'optional': value.get('optional'),
parameter_ids = []
if value.get('type'):
for par_key, par_value in value['type']:
pams =
'name': par_key,
'description': par_key.capitalize(),
'optional': par_value.get('optional'),
'type': par_value.get('type') and _return_data_type(par_value['type'].split('(')[0]) or False,
parameter_ids.append((0, 0, pams))
vals.update(parameter_ids=parameter_ids)
building_data.append((0, 0, vals))
return building_data
【讨论】:
问题是数据是未知的,所以获取 'notificaCertificadoRevocado' 是一种非常有限的方法。【参考方案2】:最后,我采用了不同的方法彻底重构了该方法。 因为我之前的代码还有一个问题。如果检查上一个所需的输出:
[(0, 0,
'name': 'SolicitudOperacionesCuis',
'description': 'Solicitud Operaciones Cuis',
'optional': False,
'parameter_ids': [
(0, 0,
'name': 'certificado',
'description': 'Certificado',
'optional': False,
'type': 'String')]
),
(0, 0,
'name': 'codigoAmbiente',
'description': 'Codigo Ambiente',
'optional': False,
'type': 'Int')]
)
]
有一个 Odoo 无法识别的嵌套 One2many 记录创建。 无论如何,由于我无法使之前的代码工作,我开始单独创建记录:
def _create_parameters(self, process_object, parameter_id=False, parent_parameter_id=False):
for key, value in process_object.items():
if key != 'optional' and key != 'type':
try:
soap_parameter = self.env['soap.parameter'].search([
'&', '&', '&', '&',
['active', '=', True],
['name', '=', key],
['description', '=', ' '.join(word.capitalize() for word in camel_case_split(key))],
['method_id', '=', self.id],
['parent_id', '=', parent_parameter_id]
], limit=1)[0]
except IndexError:
# Create parameters
soap_parameter = self.env['soap.parameter'].create(
'name': key,
'description': ' '.join(word.capitalize() for word in camel_case_split(key)),
'method_id': self.id,
'parent_id': parent_parameter_id
)
self._create_parameters(value, soap_parameter, soap_parameter.id)
if parameter_id:
if key == 'optional':
parameter_id.write('optional': value)
if key == 'type':
if isinstance(value, dict):
self._create_parameters(value, parent_parameter_id=parent_parameter_id)
else:
value_type = value.split('(')[0]
if value_type == 'Int':
value_type = 'int'
elif value_type == 'String':
value_type = 'str'
elif value_type == 'Long':
value_type = 'float'
parameter_id.write('type': value_type)
此代码将搜索并更新或创建我的参数。
【讨论】:
以上是关于如何在 Python 中使用多级字典创建 Odoo 记录的主要内容,如果未能解决你的问题,请参考以下文章