API bên ngoài¶
SoOn thường được mở rộng nội bộ thông qua các mô-đun, nhưng nhiều tính năng và tất cả dữ liệu của nó cũng có sẵn từ bên ngoài để phân tích bên ngoài hoặc tích hợp với nhiều công cụ khác nhau. Một phần của API Người mẫu có sẵn dễ dàng trên XML-RPC và có thể truy cập được từ nhiều ngôn ngữ khác nhau.
Quan trọng
Bắt đầu với PHP8, phần mở rộng XML-RPC có thể không có sẵn theo mặc định. Hãy xem hướng dẫn sử dụng để biết các bước cài đặt.
Ghi chú
Access to data via the external API is only available on Custom Odoo pricing plans. Access to the external API is not available on One App Free or Standard plans. For more information visit the Odoo pricing page or reach out to your Customer Success Manager.
Xem thêm
Sự liên quan¶
Cấu hình¶
Nếu bạn đã cài đặt máy chủ SoOn, bạn chỉ cần sử dụng các tham số của nó.
Quan trọng
Đối với các phiên bản SoOn Online (<domain>.odoo.com), người dùng được tạo mà không cần mật khẩu local (với tư cách là người mà bạn đăng nhập thông qua hệ thống xác thực SoOn Online, chứ không phải bởi chính phiên bản đó). Để sử dụng XML-RPC trên các phiên bản SoOn Online, bạn sẽ cần đặt mật khẩu trên tài khoản người dùng mà bạn muốn sử dụng:
Đăng nhập vào phiên bản của bạn bằng tài khoản quản trị viên.
Đi tới
.Nhấp vào người dùng bạn muốn sử dụng để truy cập XML-RPC.
Bấm vào Action và chọn Change Pass.
Đặt giá trị Mật khẩu mới sau đó nhấp vào Thay đổi mật khẩu.
url máy chủ là miền của phiên bản (ví dụ: https://mycompany.odoo.com), tên cơ sở dữ liệu là tên của phiên bản (ví dụ: mycompany). tên người dùng là thông tin đăng nhập của người dùng đã được định cấu hình như được hiển thị trên màn hình Thay đổi mật khẩu.
url = <insert server URL>
db = <insert database name>
username = 'admin'
password = <insert password for your admin user (default: admin)>
url = <insert server URL>
db = <insert database name>
username = "admin"
password = <insert password for your admin user (default: admin)>
$url = <insert server URL>;
$db = <insert database name>;
$username = "admin";
$password = <insert password for your admin user (default: admin)>;
final String url = <insert server URL>,
db = <insert database name>,
username = "admin",
password = <insert password for your admin user (default: admin)>;
var (
url = <insert server URL>
db = <insert database name>
username = "admin"
password = <insert password for your admin user (default: admin)>
)
Khóa API¶
Mới từ phiên bản 14.0.
SoOn hỗ trợ khóa api và (tùy thuộc vào mô-đun hoặc cài đặt) có thể yêu cầu các phím này để thực hiện các hoạt động dịch vụ web.
Cách sử dụng Khóa API trong tập lệnh của bạn là chỉ cần thay thế mật khẩu của bạn bằng khóa. Thông tin đăng nhập vẫn được sử dụng. Bạn nên lưu trữ Khóa API cẩn thận như mật khẩu vì về cơ bản chúng cung cấp cùng quyền truy cập vào tài khoản người dùng của bạn (mặc dù chúng không thể được sử dụng để đăng nhập qua giao diện).
Để thêm khóa vào tài khoản của bạn, chỉ cần truy cập Preferences (hoặc My Profile):

sau đó mở tab Account Security và nhấp vào Khóa API mới:

Nhập mô tả cho khóa, mô tả này phải rõ ràng và đầy đủ nhất có thể: đó là cách duy nhất bạn sẽ phải xác định khóa của mình sau này và biết liệu bạn nên loại bỏ chúng hay giữ chúng bên mình.
Nhấp vào Tạo khóa, sau đó sao chép khóa được cung cấp. Lưu trữ khóa này cẩn thận: nó tương đương với mật khẩu của bạn và cũng giống như mật khẩu của bạn, hệ thống sẽ không thể truy xuất hoặc hiển thị lại khóa sau này. Nếu mất chìa khóa này, bạn sẽ phải tạo một chìa khóa mới (và có thể xóa chìa khóa bạn đã mất).
Khi bạn đã định cấu hình khóa trên tài khoản của mình, chúng sẽ xuất hiện phía trên nút Khóa API mới và bạn có thể xóa chúng:

Không thể phục hồi hoặc đặt lại khóa API đã xóa. Bạn sẽ phải tạo khóa mới và cập nhật tất cả những nơi bạn đã sử dụng khóa cũ.
Cơ sở dữ liệu thử nghiệm¶
Để làm cho việc khám phá trở nên đơn giản hơn, bạn cũng có thể yêu cầu https://demo.odoo.com để có cơ sở dữ liệu thử nghiệm:
import xmlrpc.client
info = xmlrpc.client.ServerProxy('https://demo.odoo.com/start').start()
url, db, username, password = info['host'], info['database'], info['user'], info['password']
require "xmlrpc/client"
info = XMLRPC::Client.new2('https://demo.odoo.com/start').call('start')
url, db, username, password = info['host'], info['database'], info['user'], info['password']
require_once('ripcord.php');
$info = ripcord::client('https://demo.odoo.com/start')->start();
list($url, $db, $username, $password) = array($info['host'], $info['database'], $info['user'], $info['password']);
Ghi chú
Các ví dụ này sử dụng thư viện Ripcord, thư viện này cung cấp API XML-RPC đơn giản. Ripcord yêu cầu bật hỗ trợ XML-RPC trong cài đặt PHP của bạn.
Vì các lệnh gọi được thực hiện qua HTTPS nên nó cũng yêu cầu tiện ích mở rộng OpenSSL được kích hoạt.
final XmlRpcClient client = new XmlRpcClient();
final XmlRpcClientConfigImpl start_config = new XmlRpcClientConfigImpl();
start_config.setServerURL(new URL("https://demo.odoo.com/start"));
final Map<String, String> info = (Map<String, String>)client.execute(
start_config, "start", emptyList());
final String url = info.get("host"),
db = info.get("database"),
username = info.get("user"),
password = info.get("password");
Ghi chú
Các ví dụ này sử dụng thư viện XML-RPC của Apache.
Các ví dụ không bao gồm các lần nhập vì những lần nhập này không thể được dán vào mã.
client, err := xmlrpc.NewClient("https://demo.odoo.com/start", nil)
if err != nil {
log.Fatal(err)
}
info := map[string]string{}
client.Call("start", nil, &info)
url = info["host"].(string)
db = info["database"].(string)
username = info["user"].(string)
password = info["password"].(string)
Ghi chú
Những ví dụ này sử dụng thư viện github.com/kolo/xmlrpc.
Các ví dụ không bao gồm các lần nhập vì những lần nhập này không thể được dán vào mã.
Đăng nhập¶
SoOn yêu cầu người dùng API phải được xác thực trước khi họ có thể truy vấn hầu hết dữ liệu.
Điểm cuối xmlrpc/2/common
cung cấp các lệnh gọi meta không yêu cầu xác thực, chẳng hạn như chính xác thực hoặc tìm nạp thông tin phiên bản. Để xác minh xem thông tin kết nối có chính xác hay không trước khi thử xác thực, cách gọi đơn giản nhất là yêu cầu phiên bản của máy chủ. Bản thân việc xác thực được thực hiện thông qua hàm xác thực
và trả về mã định danh người dùng (uid
) được sử dụng trong các cuộc gọi được xác thực thay vì đăng nhập.
common = xmlrpc.client.ServerProxy('{}/xmlrpc/2/common'.format(url))
common.version()
common = XMLRPC::Client.new2("#{url}/xmlrpc/2/common")
common.call('version')
$common = ripcord::client("$url/xmlrpc/2/common");
$common->version();
final XmlRpcClientConfigImpl common_config = new XmlRpcClientConfigImpl();
common_config.setServerURL(new URL(String.format("%s/xmlrpc/2/common", url)));
client.execute(common_config, "version", emptyList());
client, err := xmlrpc.NewClient(fmt.Sprintf("%s/xmlrpc/2/common", url), nil)
if err != nil {
log.Fatal(err)
}
common := map[string]any{}
if err := client.Call("version", nil, &common); err != nil {
log.Fatal(err)
}
Kết quả:
{
"server_version": "13.0",
"server_version_info": [13, 0, 0, "final", 0],
"server_serie": "13.0",
"protocol_version": 1,
}
uid = common.authenticate(db, username, password, {})
uid = common.call('authenticate', db, username, password, {})
$uid = $common->authenticate($db, $username, $password, array());
int uid = (int)client.execute(common_config, "authenticate", asList(db, username, password, emptyMap()));
var uid int64
if err := client.Call("authenticate", []any{
db, username, password,
map[string]any{},
}, &uid); err != nil {
log.Fatal(err)
}
Phương thức gọi¶
Điểm cuối thứ hai là xmlrpc/2/object
. Nó được dùng để gọi các phương thức của mô hình odoo thông qua hàm RPC execute_kw
.
Mỗi lệnh gọi tới execute_kw
có các tham số sau:
cơ sở dữ liệu để sử dụng, một chuỗi
id người dùng (được truy xuất thông qua
xác thực
), một số nguyênmật khẩu của người dùng, một chuỗi
tên model, một chuỗi
tên phương thức, một chuỗi
một mảng/danh sách các tham số được truyền theo vị trí
ánh xạ/đọc chính tả các tham số để truyền theo từ khóa (tùy chọn)
Example
Ví dụ: để xem liệu chúng ta có thể đọc mô hình res.partner
hay không, chúng ta có thể gọi check_access_rights
với hoạt động
được truyền theo vị trí và raise_Exception
được truyền theo từ khóa (để có được kết quả đúng/sai thay vì đúng/lỗi):
models = xmlrpc.client.ServerProxy('{}/xmlrpc/2/object'.format(url))
models.execute_kw(db, uid, password, 'res.partner', 'check_access_rights', ['read'], {'raise_exception': False})
models = XMLRPC::Client.new2("#{url}/xmlrpc/2/object").proxy
models.execute_kw(db, uid, password, 'res.partner', 'check_access_rights', ['read'], {raise_exception: false})
$models = ripcord::client("$url/xmlrpc/2/object");
$models->execute_kw($db, $uid, $password, 'res.partner', 'check_access_rights', array('read'), array('raise_exception' => false));
final XmlRpcClient models = new XmlRpcClient() {{
setConfig(new XmlRpcClientConfigImpl() {{
setServerURL(new URL(String.format("%s/xmlrpc/2/object", url)));
}});
}};
models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "check_access_rights",
asList("read"),
new HashMap() {{ put("raise_exception", false); }}
));
models, err := xmlrpc.NewClient(fmt.Sprintf("%s/xmlrpc/2/object", url), nil)
if err != nil {
log.Fatal(err)
}
var result bool
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "check_access_rights",
[]string{"read"},
map[string]bool{"raise_exception": false},
}, &result); err != nil {
log.Fatal(err)
}
Kết quả:
true
Liệt kê hồ sơ¶
Các bản ghi có thể được liệt kê và lọc thông qua search()
.
search()
nhận bộ lọc domain bắt buộc (có thể trống) và trả về mã định danh cơ sở dữ liệu của tất cả các bản ghi khớp với bộ lọc.
Example
Để liệt kê các công ty khách hàng, ví dụ:
models.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', True]]])
models.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', true]]])
$models->execute_kw($db, $uid, $password, 'res.partner', 'search', array(array(array('is_company', '=', true))));
asList((Object[])models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "search",
asList(asList(
asList("is_company", "=", true)))
)));
var records []int64
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "search",
[]any{[]any{
[]any{"is_company", "=", true},
}},
}, &records); err != nil {
log.Fatal(err)
}
Kết quả:
[7, 18, 12, 14, 17, 19, 8, 31, 26, 16, 13, 20, 30, 22, 29, 15, 23, 28, 74]
Phân trang¶
Theo mặc định, tìm kiếm sẽ trả về id của tất cả các bản ghi khớp với điều kiện, đây có thể là một con số rất lớn. Các tham số offset
và limit
chỉ có sẵn để truy xuất một tập hợp con của tất cả các bản ghi trùng khớp.
Example
models.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', True]]], {'offset': 10, 'limit': 5})
models.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', true]]], {offset: 10, limit: 5})
$models->execute_kw($db, $uid, $password, 'res.partner', 'search', array(array(array('is_company', '=', true))), array('offset'=>10, 'limit'=>5));
asList((Object[])models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "search",
asList(asList(
asList("is_company", "=", true))),
new HashMap() {{ put("offset", 10); put("limit", 5); }}
)));
var records []int64
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "search",
[]any{[]any{
[]any{"is_company", "=", true},
}},
map[string]int64{"offset": 10, "limit": 5},
}, &records); err != nil {
log.Fatal(err)
}
Kết quả:
[13, 20, 30, 22, 29]
Đếm hồ sơ¶
Thay vì truy xuất một danh sách khổng lồ các bản ghi và đếm chúng, search_count()
có thể được sử dụng để chỉ truy xuất số lượng bản ghi phù hợp với truy vấn. Nó lấy bộ lọc domain giống như search()
và không có tham số nào khác.
Example
models.execute_kw(db, uid, password, 'res.partner', 'search_count', [[['is_company', '=', True]]])
models.execute_kw(db, uid, password, 'res.partner', 'search_count', [[['is_company', '=', true]]])
$models->execute_kw($db, $uid, $password, 'res.partner', 'search_count', array(array(array('is_company', '=', true))));
(Integer)models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "search_count",
asList(asList(
asList("is_company", "=", true)))
));
var counter int64
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "search_count",
[]any{[]any{
[]any{"is_company", "=", true},
}},
}, &counter); err != nil {
log.Fatal(err)
}
Kết quả:
19
Ghi chú
Gọi tìm kiếm
rồi gọi search_count
(hoặc ngược lại) có thể không mang lại kết quả mạch lạc nếu người dùng khác đang sử dụng máy chủ: dữ liệu được lưu trữ có thể đã thay đổi giữa các cuộc gọi.
Đọc hồ sơ¶
Dữ liệu bản ghi có thể được truy cập thông qua phương thức read()
, phương thức này lấy danh sách các id (được trả về bởi search()
) và một danh sách tùy chọn của các trường để tìm nạp. Theo mặc định, nó tìm nạp tất cả các trường mà người dùng hiện tại có thể đọc, thường là một lượng rất lớn.
Example
ids = models.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', True]]], {'limit': 1})
[record] = models.execute_kw(db, uid, password, 'res.partner', 'read', [ids])
# count the number of fields fetched by default
len(record)
ids = models.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', true]]], {limit: 1})
record = models.execute_kw(db, uid, password, 'res.partner', 'read', [ids]).first
# count the number of fields fetched by default
record.length
$ids = $models->execute_kw($db, $uid, $password, 'res.partner', 'search', array(array(array('is_company', '=', true))), array('limit'=>1));
$records = $models->execute_kw($db, $uid, $password, 'res.partner', 'read', array($ids));
// count the number of fields fetched by default
count($records[0]);
final List ids = asList((Object[])models.execute(
"execute_kw", asList(
db, uid, password,
"res.partner", "search",
asList(asList(
asList("is_company", "=", true))),
new HashMap() {{ put("limit", 1); }})));
final Map record = (Map)((Object[])models.execute(
"execute_kw", asList(
db, uid, password,
"res.partner", "read",
asList(ids)
)
))[0];
// count the number of fields fetched by default
record.size();
var ids []int64
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "search",
[]any{[]any{
[]any{"is_company", "=", true},
}},
map[string]int64{"limit": 1},
}, &ids); err != nil {
log.Fatal(err)
}
var records []any
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "read",
ids,
}, &records); err != nil {
log.Fatal(err)
}
// count the number of fields fetched by default
count := len(records)
Kết quả:
121
Ngược lại, chỉ chọn ba lĩnh vực được coi là thú vị.
models.execute_kw(db, uid, password, 'res.partner', 'read', [ids], {'fields': ['name', 'country_id', 'comment']})
models.execute_kw(db, uid, password, 'res.partner', 'read', [ids], {fields: %w(name country_id comment)})
$models->execute_kw($db, $uid, $password, 'res.partner', 'read', array($ids), array('fields'=>array('name', 'country_id', 'comment')));
asList((Object[])models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "read",
asList(ids),
new HashMap() {{
put("fields", asList("name", "country_id", "comment"));
}}
)));
var recordFields []map[string]any
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "read",
ids,
map[string][]string{
"fields": {"name", "country_id", "comment"},
},
}, &recordFields); err != nil {
log.Fatal(err)
}
Kết quả:
[{"comment": false, "country_id": [21, "Belgium"], "id": 7, "name": "Agrolait"}]
Ghi chú
Ngay cả khi trường id
không được yêu cầu, nó vẫn luôn được trả về.
Liệt kê các trường bản ghi¶
fields_get()
có thể được sử dụng để kiểm tra các trường của mô hình và kiểm tra xem trường nào có vẻ được quan tâm.
Bởi vì nó trả về một lượng lớn thông tin meta (nó cũng được sử dụng bởi các chương trình máy khách) nên nó phải được lọc trước khi in, các mục thú vị nhất đối với người dùng là chuỗi
(nhãn của trường), help` ` (văn bản trợ giúp nếu có) và ``type
(để biết giá trị nào sẽ xảy ra hoặc sẽ gửi khi cập nhật bản ghi).
Example
models.execute_kw(db, uid, password, 'res.partner', 'fields_get', [], {'attributes': ['string', 'help', 'type']})
models.execute_kw(db, uid, password, 'res.partner', 'fields_get', [], {attributes: %w(string help type)})
$models->execute_kw($db, $uid, $password, 'res.partner', 'fields_get', array(), array('attributes' => array('string', 'help', 'type')));
(Map<String, Map<String, Object>>)models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "fields_get",
emptyList(),
new HashMap() {{
put("attributes", asList("string", "help", "type"));
}}
));
recordFields := map[string]string{}
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "fields_get",
[]any{},
map[string][]string{
"attributes": {"string", "help", "type"},
},
}, &recordFields); err != nil {
log.Fatal(err)
}
Kết quả:
{
"ean13": {
"type": "char",
"help": "BarCode",
"string": "EAN13"
},
"property_account_position_id": {
"type": "many2one",
"help": "The fiscal position will determine taxes and accounts used for the partner.",
"string": "Fiscal Position"
},
"signup_valid": {
"type": "boolean",
"help": "",
"string": "Signup Token is Valid"
},
"date_localization": {
"type": "date",
"help": "",
"string": "Geo Localization Date"
},
"ref_company_ids": {
"type": "one2many",
"help": "",
"string": "Companies that refers to partner"
},
"sale_order_count": {
"type": "integer",
"help": "",
"string": "# of Sales Order"
},
"purchase_order_count": {
"type": "integer",
"help": "",
"string": "# of Purchase Order"
},
Tìm kiếm và đọc¶
Vì đây là một nhiệm vụ rất phổ biến nên SoOn cung cấp một lối tắt search_read()
, như tên gọi của nó, tương đương với một search()
theo sau bởi read()
, nhưng tránh phải thực hiện hai yêu cầu và giữ id xung quanh.
Các đối số của nó tương tự như search()
, nhưng nó cũng có thể lấy danh sách fields
(như read()
, nếu danh sách đó không được cung cấp, nó sẽ tìm nạp tất cả các trường của bản ghi trùng khớp).
Example
models.execute_kw(db, uid, password, 'res.partner', 'search_read', [[['is_company', '=', True]]], {'fields': ['name', 'country_id', 'comment'], 'limit': 5})
models.execute_kw(db, uid, password, 'res.partner', 'search_read', [[['is_company', '=', true]]], {fields: %w(name country_id comment), limit: 5})
$models->execute_kw($db, $uid, $password, 'res.partner', 'search_read', array(array(array('is_company', '=', true))), array('fields'=>array('name', 'country_id', 'comment'), 'limit'=>5));
asList((Object[])models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "search_read",
asList(asList(
asList("is_company", "=", true))),
new HashMap() {{
put("fields", asList("name", "country_id", "comment"));
put("limit", 5);
}}
)));
var recordFields []map[string]any
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "search_read",
[]any{[]any{
[]any{"is_company", "=", true},
}},
map[string]any{
"fields": []string{"name", "country_id", "comment"},
"limit": 5,
},
}, &recordFields); err != nil {
log.Fatal(err)
}
Kết quả:
[
{
"comment": false,
"country_id": [ 21, "Belgium" ],
"id": 7,
"name": "Agrolait"
},
{
"comment": false,
"country_id": [ 76, "France" ],
"id": 18,
"name": "Axelor"
},
{
"comment": false,
"country_id": [ 233, "United Kingdom" ],
"id": 12,
"name": "Bank Wealthy and sons"
},
{
"comment": false,
"country_id": [ 105, "India" ],
"id": 14,
"name": "Best Designers"
},
{
"comment": false,
"country_id": [ 76, "France" ],
"id": 17,
"name": "Camptocamp"
}
]
Tạo bản ghi¶
Các bản ghi của một mô hình được tạo bằng cách sử dụng create()
. Phương thức này tạo một bản ghi duy nhất và trả về mã định danh cơ sở dữ liệu của nó.
create()
ánh xạ các trường tới các giá trị, được sử dụng để khởi tạo bản ghi. Đối với bất kỳ trường nào có giá trị mặc định và không được đặt thông qua đối số ánh xạ, giá trị mặc định sẽ được sử dụng.
Example
id = models.execute_kw(db, uid, password, 'res.partner', 'create', [{'name': "New Partner"}])
id = models.execute_kw(db, uid, password, 'res.partner', 'create', [{name: "New Partner"}])
$id = $models->execute_kw($db, $uid, $password, 'res.partner', 'create', array(array('name'=>"New Partner")));
final Integer id = (Integer)models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "create",
asList(new HashMap() {{ put("name", "New Partner"); }})
));
var id int64
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "create",
[]map[string]string{
{"name": "New Partner"},
},
}, &id); err != nil {
log.Fatal(err)
}
Kết quả:
78
Cảnh báo
Trong khi hầu hết các loại giá trị đều như mong đợi (số nguyên cho Integer
, chuỗi cho Char
hoặc Text
),
Các trường
Date
,Datetime
vàBinary
sử dụng giá trị chuỗiOne2many
vàMany2many
sử dụng giao thức lệnh đặc biệt được nêu chi tiết trongtài liệu về phương thức ghi
.
Cập nhật hồ sơ¶
Các bản ghi có thể được cập nhật bằng write()
. Nó cần một danh sách các bản ghi để cập nhật và ánh xạ các trường đã cập nhật tới các giá trị tương tự như create()
.
Nhiều bản ghi có thể được cập nhật đồng thời, nhưng tất cả chúng sẽ nhận cùng giá trị cho các trường được đặt. Không thể thực hiện cập nhật "được tính toán" (trong đó giá trị được đặt phụ thuộc vào giá trị hiện có của bản ghi).
Example
models.execute_kw(db, uid, password, 'res.partner', 'write', [[id], {'name': "Newer partner"}])
# get record name after having changed it
models.execute_kw(db, uid, password, 'res.partner', 'read', [[id], ['display_name']])
models.execute_kw(db, uid, password, 'res.partner', 'write', [[id], {name: "Newer partner"}])
# get record name after having changed it
models.execute_kw(db, uid, password, 'res.partner', 'read', [[id], ['display_name']])
$models->execute_kw($db, $uid, $password, 'res.partner', 'write', array(array($id), array('name'=>"Newer partner")));
// get record name after having changed it
$models->execute_kw($db, $uid, $password,
'res.partner', 'read', array(array($id), array('display_name')));
models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "write",
asList(
asList(id),
new HashMap() {{ put("name", "Newer Partner"); }}
)
));
// get record name after having changed it
asList((Object[])models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "read",
asList(asList(id), asList("display_name"))
)));
var result bool
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "write",
[]any{
[]int64{id},
map[string]string{"name": "Newer partner"},
},
}, &result); err != nil {
log.Fatal(err)
}
// get record name after having changed it
var record []any
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "name_get",
[]any{
[]int64{id},
},
}, &record); err != nil {
log.Fatal(err)
}
Kết quả:
[[78, "Newer partner"]]
Xóa bản ghi¶
Các bản ghi có thể bị xóa hàng loạt bằng cách cung cấp id của chúng cho unlink()
.
Example
models.execute_kw(db, uid, password, 'res.partner', 'unlink', [[id]])
# check if the deleted record is still in the database
models.execute_kw(db, uid, password, 'res.partner', 'search', [[['id', '=', id]]])
models.execute_kw(db, uid, password, 'res.partner', 'unlink', [[id]])
# check if the deleted record is still in the database
models.execute_kw(db, uid, password, 'res.partner', 'search', [[['id', '=', id]]])
$models->execute_kw($db, $uid, $password, 'res.partner', 'unlink', array(array($id)));
// check if the deleted record is still in the database
$models->execute_kw(
$db, $uid, $password, 'res.partner', 'search', array(array(array('id', '=', $id)))
);
models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "unlink",
asList(asList(id))));
// check if the deleted record is still in the database
asList((Object[])models.execute("execute_kw", asList(
db, uid, password,
"res.partner", "search",
asList(asList(asList("id", "=", 78)))
)));
var result bool
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "unlink",
[]any{
[]int64{id},
},
}, &result); err != nil {
log.Fatal(err)
}
// check if the deleted record is still in the database
var record []any
if err := models.Call("execute_kw", []any{
db, uid, password,
"res.partner", "search",
[]any{[]any{
[]any{"id", "=", id},
}},
}, &record); err != nil {
log.Fatal(err)
}
Kết quả:
[]
Kiểm tra và nội tâm¶
Mặc dù trước đây chúng tôi đã sử dụng fields_get()
để truy vấn một mô hình và đã sử dụng một mô hình tùy ý ngay từ đầu, SoOn lưu trữ hầu hết siêu dữ liệu mô hình bên trong một vài siêu mô hình cho phép cả truy vấn hệ thống và thay đổi các mô hình và trường (với một số hạn chế) nhanh chóng qua XML-RPC.
ir.model
¶
Cung cấp thông tin về các mô hình SoOn thông qua các lĩnh vực khác nhau.
tên
mô tả mà con người có thể đọc được về mô hình
người mẫu
tên từng model trong hệ thống
nhà nước
mô hình được tạo bằng mã Python (
base
) hay bằng cách tạo bản ghiir.model
(`` manual``)field_id
danh sách các trường của mô hình thông qua
One2many
đến ir.model.fieldsview_ids
One2many
vào Xem kiến trúc được xác định cho mô hìnhaccess_ids
One2many
liên quan đến Quyền truy cập được đặt trên mô hình
ir.model
có thể được sử dụng để
Truy vấn hệ thống về các mô hình đã cài đặt (làm điều kiện tiên quyết cho các thao tác trên mô hình hoặc để khám phá nội dung của hệ thống).
Nhận thông tin về một mô hình cụ thể (thường bằng cách liệt kê các trường liên quan đến nó).
Tạo mô hình mới một cách linh hoạt trên RPC.
Quan trọng
Tên mẫu tùy chỉnh phải bắt đầu bằng
x_
.trạng thái
phải được cung cấp và đặt thànhthủ công
, nếu không mô hình sẽ không được tải.Không thể thêm phương thức mới vào mô hình tùy chỉnh, chỉ các trường.
Example
Một mô hình tùy chỉnh ban đầu sẽ chỉ chứa các trường "tích hợp" có sẵn trên tất cả các mô hình:
models.execute_kw(db, uid, password, 'ir.model', 'create', [{
'name': "Custom Model",
'model': "x_custom_model",
'state': 'manual',
}])
models.execute_kw(db, uid, password, 'x_custom_model', 'fields_get', [], {'attributes': ['string', 'help', 'type']})
$models->execute_kw($db, $uid, $password, 'ir.model', 'create', array(array(
'name' => "Custom Model",
'model' => 'x_custom_model',
'state' => 'manual'
)));
$models->execute_kw($db, $uid, $password, 'x_custom_model', 'fields_get', array(), array('attributes' => array('string', 'help', 'type')));
models.execute_kw(db, uid, password, 'ir.model', 'create', [{
name: "Custom Model",
model: 'x_custom_model',
state: 'manual'
}])
fields = models.execute_kw(db, uid, password, 'x_custom_model', 'fields_get', [], {attributes: %w(string help type)})
models.execute(
"execute_kw", asList(
db, uid, password,
"ir.model", "create",
asList(new HashMap<String, Object>() {{
put("name", "Custom Model");
put("model", "x_custom_model");
put("state", "manual");
}})
));
final Object fields = models.execute(
"execute_kw", asList(
db, uid, password,
"x_custom_model", "fields_get",
emptyList(),
new HashMap<String, Object> () {{
put("attributes", asList(
"string",
"help",
"type"));
}}
));
var id int64
if err := models.Call("execute_kw", []any{
db, uid, password,
"ir.model", "create",
[]map[string]string{
{
"name": "Custom Model",
"model": "x_custom_model",
"state": "manual",
},
},
}, &id); err != nil {
log.Fatal(err)
}
recordFields := map[string]string{}
if err := models.Call("execute_kw", []any{
db, uid, password,
"x_custom_model", "fields_get",
[]any{},
map[string][]string{
"attributes": {"string", "help", "type"},
},
}, &recordFields); err != nil {
log.Fatal(err)
}
Kết quả:
{
"create_uid": {
"type": "many2one",
"string": "Created by"
},
"create_date": {
"type": "datetime",
"string": "Created on"
},
"__last_update": {
"type": "datetime",
"string": "Last Modified on"
},
"write_uid": {
"type": "many2one",
"string": "Last Updated by"
},
"write_date": {
"type": "datetime",
"string": "Last Updated on"
},
"display_name": {
"type": "char",
"string": "Display Name"
},
"id": {
"type": "integer",
"string": "Id"
}
}
ir.model.fields
¶
Cung cấp thông tin về các trường của mô hình SoOn và cho phép thêm các trường tùy chỉnh mà không cần sử dụng mã Python.
model_id
Many2one
tới ir.model mà trường thuộc vềtên
tên kỹ thuật của trường (được sử dụng trong
đọc
hoặcwrite
)field_description
nhãn mà người dùng có thể đọc được của trường (ví dụ:
chuỗi
trongfields_get
)ttype
type của trường cần tạo
nhà nước
trường được tạo thông qua mã Python (
base
) hay thông quair.model.fields
(manual
)bắt buộc
,chỉ đọc
,dịch
bật cờ tương ứng trên trường
nhóm
kiểm soát truy cập cấp trường, a
Many2many
tớires.groups
selection
,size
,on_delete
,relation
,relation_field
,domain
các thuộc tính và tùy chỉnh dành riêng cho từng loại, hãy xem tài liệu về trường để biết chi tiết
Quan trọng
Giống như các mô hình tùy chỉnh, chỉ các trường mới được tạo bằng
state="manual"
mới được kích hoạt dưới dạng các trường thực tế trên mô hình.Không thể thêm các trường được tính toán thông qua
ir.model.fields
, một số thông tin meta trường (mặc định, onchange) cũng không thể được đặt.
Example
id = models.execute_kw(db, uid, password, 'ir.model', 'create', [{
'name': "Custom Model",
'model': "x_custom",
'state': 'manual',
}])
models.execute_kw(db, uid, password, 'ir.model.fields', 'create', [{
'model_id': id,
'name': 'x_name',
'ttype': 'char',
'state': 'manual',
'required': True,
}])
record_id = models.execute_kw(db, uid, password, 'x_custom', 'create', [{'x_name': "test record"}])
models.execute_kw(db, uid, password, 'x_custom', 'read', [[record_id]])
$id = $models->execute_kw($db, $uid, $password, 'ir.model', 'create', array(array(
'name' => "Custom Model",
'model' => 'x_custom',
'state' => 'manual'
)));
$models->execute_kw($db, $uid, $password, 'ir.model.fields', 'create', array(array(
'model_id' => $id,
'name' => 'x_name',
'ttype' => 'char',
'state' => 'manual',
'required' => true
)));
$record_id = $models->execute_kw($db, $uid, $password, 'x_custom', 'create', array(array('x_name' => "test record")));
$models->execute_kw($db, $uid, $password, 'x_custom', 'read', array(array($record_id)));
id = models.execute_kw(db, uid, password, 'ir.model', 'create', [{
name: "Custom Model",
model: "x_custom",
state: 'manual'
}])
models.execute_kw(db, uid, password, 'ir.model.fields', 'create', [{
model_id: id,
name: "x_name",
ttype: "char",
state: "manual",
required: true
}])
record_id = models.execute_kw(db, uid, password, 'x_custom', 'create', [{x_name: "test record"}])
models.execute_kw(db, uid, password, 'x_custom', 'read', [[record_id]])
final Integer id = (Integer)models.execute(
"execute_kw", asList(
db, uid, password,
"ir.model", "create",
asList(new HashMap<String, Object>() {{
put("name", "Custom Model");
put("model", "x_custom");
put("state", "manual");
}})
));
models.execute(
"execute_kw", asList(
db, uid, password,
"ir.model.fields", "create",
asList(new HashMap<String, Object>() {{
put("model_id", id);
put("name", "x_name");
put("ttype", "char");
put("state", "manual");
put("required", true);
}})
));
final Integer record_id = (Integer)models.execute(
"execute_kw", asList(
db, uid, password,
"x_custom", "create",
asList(new HashMap<String, Object>() {{
put("x_name", "test record");
}})
));
client.execute(
"execute_kw", asList(
db, uid, password,
"x_custom", "read",
asList(asList(record_id))
));
var id int64
if err := models.Call("execute_kw", []any{
db, uid, password,
"ir.model", "create",
[]map[string]string{
{
"name": "Custom Model",
"model": "x_custom",
"state": "manual",
},
},
}, &id); err != nil {
log.Fatal(err)
}
var fieldId int64
if err := models.Call("execute_kw", []any{
db, uid, password,
"ir.model.fields", "create",
[]map[string]any{
{
"model_id": id,
"name": "x_name",
"ttype": "char",
"state": "manual",
"required": true,
},
},
}, &fieldId); err != nil {
log.Fatal(err)
}
var recordId int64
if err := models.Call("execute_kw", []any{
db, uid, password,
"x_custom", "create",
[]map[string]string{
{"x_name": "test record"},
},
}, &recordId); err != nil {
log.Fatal(err)
}
var recordFields []map[string]any
if err := models.Call("execute_kw", []any{
db, uid, password,
"x_custom", "read",
[][]int64{{recordId}},
}, recordFields); err != nil {
log.Fatal(err)
}
Kết quả:
[
{
"create_uid": [1, "Administrator"],
"x_name": "test record",
"__last_update": "2014-11-12 16:32:13",
"write_uid": [1, "Administrator"],
"write_date": "2014-11-12 16:32:13",
"create_date": "2014-11-12 16:32:13",
"id": 1,
"display_name": "test record"
}
]