如何使用 XMLRPC 在 Odoo 中写入字段 many2one

How to write fields many2one in Odoo with XMLRPC

我想为模型“product.category”使用 xmlrpc。

如何在PYTHON中用“read and search”写字段“categ_id”?我总是出错。我需要这样做,因为我必须将这些信息传输到另一个数据库 Odoo。

    import xmlrpc.client
    import time
    url_db1="http://localhost:8069"
    db_1='DB_ONE'
    username_db_1='username'
    password_db_1='password'

    common_1 = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url_db1))
    models_1 = xmlrpc.client.ServerProxy('{}/xmlrpc/2/object'.format(url_db1))
    version_db1 = common_1.version()

    print("details..", version_db1)


    url_db2="http://localhost:806972"
    db_2='DB_2'
    username_db_2='myemail'
    password_db_2='mypassword'

    common_2 = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url_db2))
    models_2 = xmlrpc.client.ServerProxy('{}/xmlrpc/2/object'.format(url_db2))
    version_db2 = common_2.version()

    print("details..", version_db2)


    uid_db1 = common_1.authenticate(db_1, username_db_1, password_db_1, {})
    uid_db2 = common_2.authenticate(db_2, username_db_2, password_db_2, {})

    db_1_categories = models_1.execute_kw(db_1, uid_db1, password_db_1, 'product.category', 'search_read', [[]], {'fields':['id','name', 'parent_id']})

    total_count = 0
    for category in db_1_categories:
        print("category..", category)
        total_count +=1
        values = {}
        values['id'] = category['id']
        values['name'] = category['name']
        if category['parent_id']:
            values['parent_id'] = category['parent_id'][0]
        new_lead = models_2.execute_kw(db_2, uid_db2, password_db_2, 'product.category', 'create', [values])
print("Total Created..", total_count)

这是错误: 验证错误: ('The operation cannot be completed: another model requires the record being deleted. If possible, archive it instead.\n\nModel: Product Category (product.category), Constraint: product_category_parent_id_fkey', None)\n'>

方法名应该是search_read

例子:

models.execute_kw(db, uid, password,
   'product.template', 'search_read',
    [],
    {'fields': ['name', 'default_code', 'categ_id']})

应该是return一个字典列表,categ_id字段值是一个包含两个值的列表,第一个是类别的id,第二个是类别的名称。

writecateg_id,您只需要将类别ID提供给write方法即可。

示例:

product_template_data = [{'default_code': 'FURN_6666', 'categ_id': [8, 'All / Saleable / Office Furniture'], 'id': 23, 'name': 'Acoustic Bloc Screens'}, ...] 

for ptd in product_template_data:
    models.execute_kw(db, uid, password, 'product.template', 'write', 
        [[ptd['id']], 
        {
            'categ_id': ptd['categ_id'][0],
            ...
        }
    ])

你提到你需要将数据传输到另一个数据库,产品模板可能不存在这意味着你不能调用 write 方法,你可以调用 create 方法。

示例:

id = models.execute_kw(db, uid, password, 'product.template', 'create', [{
    'categ_id': ptd['categ_id'][0],
    ...
}])  

编辑:
你会得到一个无效的语法错误:

[product,'categ_id': product['categ_id'][0],]

要将值传递给 create 方法,您需要将 args 作为列表传递给 execute_kw 方法,然后在该列表中将值作为字典传递。

编辑:


values = {}
values['name'] = product['name']
values['categ_id'] = product['categ_id'][0]
...
new_lead = models_2.execute_kw(db_2, uid_db2, password_db_2, 'product.template', 'create', [values])

编辑:在新数据库中使用父类别id

当我们调用 create 方法时,它会创建一个新记录 return 它的 ID 这可能与通过 values 字典传递的记录不同。

为避免 ValidationError,您可以使用字典,其中旧数据库中的父 ID 是键,新 ID 是值,然后您只需在创建新类别时传递该值。

category_ids = {}
for category in db_1_categories:
        print("category..", category)
        total_count +=1
        values = {}
        # values['id'] = category['id']
        values['name'] = category['name']
        if category['parent_id']:
            values['parent_id'] = category_ids[category['parent_id'][0]]
        category_id = models_2.execute_kw(db_2, uid_db2, password_db_2, 'product.category', 'create', [values])
        category_ids[category['id']] = category_id

首先是你的代码出错

这是您的代码

db_1_products = models_1.execute_kw(db_1, uid_db1, password_db_1, 'product.template', 'search_read', [[ ]], {'fields':['id','name','categ_id','type','default_code','list_price','website_url', 'inventory_availibility', 'website_description']})

total_count = 0
for product in db_1_products:
    print("produt..", product)
    total_count +=1
    new_lead = models_2.execute_kw(db_2, uid_db2, password_db_2, 'product.template', 'create', [product,'categ_id': product['categ_id'][0],])

print("创建总数..", total_count)

这是更新后的代码

db_1_products = models_1.execute_kw(db_1, uid_db1, password_db_1, 'product.template', 'search_read', [[ ]], {'fields':['id','name','categ_id','type','default_code','list_price','website_url', 'inventory_availibility', 'website_description']})

total_count = 0
for product in db_1_products:
    print("produt..", product)
    total_count +=1
    new_lead = models_2.execute_kw(db_2, uid_db2, password_db_2, 'product.template', 'create', [{product,'categ_id': product['categ_id'][0]}])

print("创建总数..", total_count)

在 odoo 中创建任何模型时都需要传递字典。