如何在 Python 中使用多级词典创建 Odoo 记录
How to create Odoo records with multilevel dictionaries in Python
我正在努力创建一种递归方法来在 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
这工作很好,只有一个问题,正在 returned 的数据具有以下形式:
[(0, 0, {
'name': 'SolicitudOperacionesCuis',
'description': 'Solicitud Operaciones Cuis',
'optional': False,
'parameter_ids': [
(0, 0, {
'name': 'codigoAmbiente',
'description': 'Codigo Ambiente',
'optional': False,
'type': 'Int'})]
})
]
问题是处理其中一个子参数后的方法因“return parameter_list”部分而停止。 (我什至在问题部分添加了 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'})]
})
]
我应该如何调整我的方法来实现这个目标?
使用递归方法很难!
最后我采取了另一种方法,彻底重构了该方法。
因为我之前的代码还有一个问题。如果检查之前的期望输出:
[(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})
此代码将搜索和更新或创建我的参数。
如果输入数据是已知的,而且似乎有用的数据是输入字典中的数据,则不需要递归元素。
更新了下面输出您预期输出的类似函数
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
我正在努力创建一种递归方法来在 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
这工作很好,只有一个问题,正在 returned 的数据具有以下形式:
[(0, 0, {
'name': 'SolicitudOperacionesCuis',
'description': 'Solicitud Operaciones Cuis',
'optional': False,
'parameter_ids': [
(0, 0, {
'name': 'codigoAmbiente',
'description': 'Codigo Ambiente',
'optional': False,
'type': 'Int'})]
})
]
问题是处理其中一个子参数后的方法因“return parameter_list”部分而停止。 (我什至在问题部分添加了 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'})]
})
]
我应该如何调整我的方法来实现这个目标? 使用递归方法很难!
最后我采取了另一种方法,彻底重构了该方法。 因为我之前的代码还有一个问题。如果检查之前的期望输出:
[(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})
此代码将搜索和更新或创建我的参数。
如果输入数据是已知的,而且似乎有用的数据是输入字典中的数据,则不需要递归元素。 更新了下面输出您预期输出的类似函数
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