フロントサイド(ブラウザ)がどのようにデータを取得してるかザックリ見てみます
メニュークリックは最初クリックファンクションを通ってるはずなので、
アドレスバーに
http://localhost:8069/web#action=196&cids=1&menu_id=141&model=fleet.vehicle.cost&view_type=kanban
を入力しGETした時の リクエストとレスポンスを見てみます
| 1 | web | GET |
| 2 | Stylesheet | web.assets_common.css |
| 3 | Script | web.assets_common.js |
| 4 | Script | web.assets_backend.js |
| 5 | Stylesheet | web.assets_backend.css |
| 6 | XHR | c42557850146c48e79b10df262c4d92fc6b2a7f6 |
| 7 | XHR | b2f93d2c1bf683f8179b38c4bac3898e73d640b0?mods=base…rating,website_theme_install,website_slides,fleet |
| 8 | Font | fontawesome-webfont.woff2?v=4.7.0 |
| 9 | Font | Roboto-Regular.ttf |
| 10 | XHR | 43b43ad26854cef051d093fc0d6ab0a89b2573e6?mods=base…theme_install%2Cwebsite_slides%2Cfleet&lang=ja_JP |
| 11 | Script | ja_JP |
| 12 | XHR | init_messaging |
| 13 | XHR | debug.xml?debug=1610843633460 |
| 14 | XHR | systray_get_activities |
| 15 | Image | user_menu_avatar.png |
| 16 | Image | image?model=res.users&field=image_128&id=2 |
| 17 | XHR | poll |
| 18 | XHR | check_access_rights |
| 19 | Image | icon.png |
| 20 | Image | icon.png |
| 21 | XHR | load |
| 22 | XHR | load_views |
| 23 | XHR | web_read_group |
| 24 | Script | jquery.touchSwipe.js |
| 25 | XHR | search_read |
| 26 | XHR | notify |
No1 一発目 GETで
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"/>
<title>Odoo</title>
<link type="image/x-icon" rel="shortcut icon" href="/web/static/src/img/favicon.ico"/>
<script type="text/javascript">
var odoo = {
csrf_token: "fca9e0b3d87a9d647a990f8a0848db4e6d875037o",
debug: "1",
};
</script>
<script type="text/javascript">
//※odoo.session_infを連想配列形式で定義
odoo.session_info = {"uid": 2, "is_system": true, "is_admin": true, "user_context": {"lang": "ja_JP", "tz": "Asia/Tokyo", "uid": 2}, "db": "odoo", "server_version": "13.0-20200710", "server_version_info": [13, 0, 0, "final", 0, ""], "name": "Mitchell Admin", "username": "dontaxmewhy@yahoo.co.jp", "partner_display_name": "YourCompany, Mitchell Admin", "company_id": 1, "partner_id": 3, "web.base.url": "http://localhost:8069", "user_companies": {"current_company": [1, "YourCompany"], "allowed_companies": [[1, "YourCompany"]]}, "currencies": {"1": {"symbol": "\u20ac", "position": "after", "digits": [69, 2]}, "25": {"symbol": "\u00a5", "position": "before", "digits": [69, 0]}, "2": {"symbol": "$", "position": "before", "digits": [69, 2]}}, "show_effect": "True", "display_switch_company_menu": false, "cache_hashes": {"load_menus": "afd2d1dabaffb12f492cfdeced11820e3a44332a", "qweb": "3c22572d90e4f3c8a7cb63bdd36f9ee746e7fcea", "translations": "ee10768d12da2d0a4ddf27e5501b0f09a7ac836e"}, "web_tours": [], "out_of_office_message": false};
//※odoo.reloadMenusに無名関数を代入
odoo.reloadMenus = function () {
return new Promise(function(resolve, reject) {
function onLoaded() {
resolve(oReq.response);
}
//※XMLHttpRequest(Ajax)-メニュー
var oReq = new XMLHttpRequest();
oReq.responseType = "json";
oReq.addEventListener("load", onLoaded);
oReq.addEventListener("error", reject);
oReq.open("GET", '/web/webclient/load_menus/' + odoo.session_info.cache_hashes.load_menus);
oReq.send();
});
}
odoo.loadMenusPromise = odoo.reloadMenus();
//("cache_hashes": {"load_menus": "afd2d1dabaffb12f492cfdeced11820e3a44332a"
</script>
<link type="text/css" rel="stylesheet" href="/web/content/452-18899c5/web.assets_common.css"/>
<link type="text/css" rel="stylesheet" href="/web/content/532-bb2031a/web.assets_backend.css"/>
<script type="text/javascript" src="/web/content/454-18899c5/web.assets_common.js"></script>
<script type="text/javascript" src="/web/content/533-bb2031a/web.assets_backend.js"></script>
<!--[if lt IE 10]>
<body class="ie9">
<![endif]-->
<script type="text/javascript">
//※実際に動くのはココ
odoo.define('web.web_client', function (require) {
var WebClient = require('web.WebClient');
var web_client = new WebClient();
//※jQuery予約関数
$(function() {
web_client.setElement($(document.body));
web_client.start();
});
return web_client;
});
</script>
</head>
<body class="o_web_client">
</body>
</html>
最初のdocumentを読み込んだ後
//※jQuery予約関数
$(function() {
web_client.setElement($(document.body));
web_client.start();
});
が動く。
順にdocument のロード
No6のレスポンスが以下
メニューリストの読み込みです
{
"id":false,
"name":"root",
"parent_id":[
-1,
""
],
"children":[
{
"id":88,
"name":"ディスカス",
"sequence":1,
"parent_id":false,
"action":"ir.actions.client,109",
"web_icon":"mail,static/description/icon.png",
"web_icon_data":"iVBORw0KGgoAAAANSUhEUgAAAIwA(Base64デコード)",
"children":{
},
"xmlid":"mail.menu_root_discuss"
},
{
"id":96,
"name":"カレンダ",
"sequence":2,
"parent_id":false,
"action":"ir.actions.act_window,127",
"web_icon":"calendar,static/description/icon.png",
"web_icon_data":"iVBORw0KGgoAAAANSUhEUg(Base64デコード)",
"children":{
},
"xmlid":"calendar.mail_menu_calendar"
},
{
"id":100,
"name":"連絡先",
"sequence":4,
"parent_id":false,
"action":false,
"web_icon":"contacts,static/description/icon.png",
"web_icon_data":"iVBORw0KGgoAAAANSUhEUg(Base64デコード)",
"children":[
{
"id":101,
"name":"連絡先",
"sequence":2,
"parent_id":[
100,
"連絡先"
],
"action":"ir.actions.act_window,129",
"web_icon":false,
"web_icon_data":false,
"children":{
},
"xmlid":"contacts.res_partner_menu_contacts"
},
{
"id":102,
"name":"設定",
"sequence":2,
"parent_id":[
100,
"連絡先"
],
"action":false,
"web_icon":false,
"web_icon_data":false,
"children":[
{
"id":103,
"name":"連絡先タグ",
"sequence":1,
"parent_id":[
102,
"連絡先/設定"
],
"action":"ir.actions.act_window,62",
"web_icon":false,
"web_icon_data":false,
"children":{
},
"xmlid":"contacts.menu_partner_category_form"
},
{
"id":104,
"name":"連絡先敬称",
"sequence":3,
"parent_id":[
102,
"連絡先/設定"
],
"action":"ir.actions.act_window,56",
"web_icon":false,
"web_icon_data":false,
"children":{
},
"xmlid":"contacts.menu_partner_title_contact"
},
{
"id":105,
"name":"活動セクタ",
"sequence":4,
"parent_id":[
102,
"連絡先/設定"
],
"action":"ir.actions.act_window,63",
"web_icon":false,
"web_icon_data":false,
"children":{
},
"xmlid":"contacts.res_partner_industry_menu"
},
~省略~
"xmlid":""
}
こんな感じで読み込んでパースしていく
ポイントは
21 XHR load
22 XHRload_views
23 XHRweb_read_group
あたりか
XHR load で画面構成情報を読み込み
XHRload_viewsでview定義<xml>の情報を取得(json)
XHRweb_read_group でデータを取得
jsonパースしてdocumentボディにセット
超ザックリこんな感じみたいです
