Author: |
My Company |
License: |
no license |
Branch: |
15.0 |
Repository: |
twtrubiks/odoo-demo-addons-tutorial |
Dependencies: |
web |
Languages: |
Markdown (147, 53.3%),
and
Python (129, 46.7%) |
<h1>odoo 15 教學 - 透過 controller jsonrpc 建立簡易 REST API</h1>
<ul>
<li><a href="">(等待新增)Youtube Tutorial - 透過 controller jsonrpc 建立簡易 REST API</a></li>
</ul>
<p>之前在 <a href="https://github.com/twtrubiks/odoo-demo-addons-tutorial/tree/14.0/demo_controller_json">odoo 14 教學 - 透過 controller 建立簡單 api</a> 這篇文章中,</p>
<p>有教大家簡單的透過 controller 建立 api,</p>
<p>今天要更進一步, 加上 <code>auth=users</code> 以及透過 <code>jsonrpc</code> 打造類似 REST API 的範例.</p>
<h2>說明</h2>
<p>首先把 addons 裝起來,</p>
<p><a href="https://github.com/twtrubiks/odoo-demo-addons-tutorial/blob/15.0/demo_controller_api/demo_controller_api_jsonrpc/controllers/api.py">demo<em>controller</em>api_jsonrpc/controllers/api.py</a></p>
<p>```python
from odoo import http, _
from odoo.http import request
import json</p>
<p>class DemoApiController(http.Controller):
def get<em>res</em>users(self, pk=None):
if pk:
domain = [("id", "=", pk)]
else:
domain = []</p>
<pre><code> return [
{
"id": record.id,
"name": record.name,
"company": record.company_id.name,
"phone": record.phone,
"email": record.email,
}
for record in request.env["res.users"].sudo().search(domain)
]
@http.route("/api/users/<string:pk>", methods=["GET"], type="json", auth="user")
def api_get_res_users(self, pk=None):
return json.dumps(self.get_res_users(pk))
@http.route("/api/users/", methods=["GET"], type="json", auth="user")
def api_get_res_user(self):
return json.dumps(self.get_res_users())
@http.route("/api/users/", methods=["POST"], type="json", auth="user")
def api_post_res_user(self):
param = request.jsonrequest
if not param["login"]:
return json.dumps("login not allow empty")
vals = {
"name": param["name"],
"phone": param["phone"],
"email": param["email"],
"login": param["login"],
}
if request.env["res.users"].sudo().search([("login", "=", param["login"])]):
return json.dumps("already exists")
res_user = request.env["res.users"].sudo().create(vals)
return json.dumps(self.get_res_users(res_user.id))
@http.route("/api/users/<string:pk>", methods=["PATCH"], type="json", auth="user")
def api_patch_res_user(self, pk=None):
param = request.jsonrequest
res_user = request.env["res.users"].sudo().search([("id", "=", pk)])
if not res_user:
return json.dumps("not exists")
res_user.phone = param["phone"]
return json.dumps(self.get_res_users(pk))
</code></pre>
<p>```</p>
<p>注意這邊 controller 定義的都是 <code>type="json"</code>.</p>
<p>這邊主要建立了幾個 api, 分別是</p>
<p><code>GET</code> <code>/api/users/</code> 取得全部 <code>res_users</code>.</p>
<p><code>GET</code> <code>/api/users/<string:pk></code> 取得特定 <code>res_users</code>.</p>
<p><code>POST</code> <code>/api/users/</code> 新增 <code>res_users</code>.</p>
<p><code>PATCH</code> <code>/api/users/<string:pk></code> 修改特定 <code>res_users</code> 資料.</p>
<h2>client 端</h2>
<p><a href="https://github.com/twtrubiks/odoo-demo-addons-tutorial/blob/15.0/demo_controller_api/demo_controller_api_jsonrpc/client.py">client.py</a> 端的部份就是直接執行</p>
<p><code>cmd
python3 client.py
</code></p>
<p>執行畫面, 這邊用 <code>get_users()</code> 示範,</p>
<p><img src="https://i.imgur.com/112g6pR.png" alt="alt tag"></p>
<p>```python
import requests
import json</p>
<p>HOST = "http://0.0.0.0:8069"
AUTH_URL = "{}/web/session/authenticate/".format(HOST)</p>
<p>headers = {
"Content-Type": "application/json",
"Accept": "application/json",
}</p>
<p>session_data = {
"jsonrpc": "2.0",
"params": {
"login": "admin",
"password": "admin",
"db": "odoo",
},
}</p>
<p>def get<em>session</em>id():
res = requests.post(AUTH<em>URL, data=json.dumps(session</em>data), headers=headers)
session<em>id = res.cookies["session</em>id"]
return session_id</p>
<p>def get<em>users():
base</em>url = "{}/api/users/".format(HOST)</p>
<pre><code>res = requests.get(
base_url,
data=json.dumps({}),
headers=headers,
cookies={"session_id": get_session_id()},
)
print(res.json())
</code></pre>
<p>def get<em>user():
base</em>url = "{}/api/users/3/".format(HOST)</p>
<pre><code>res = requests.get(
base_url,
data=json.dumps({}),
headers=headers,
cookies={"session_id": get_session_id()},
)
print(res.json())
</code></pre>
<p>def add<em>user():
base</em>url = "{}/api/users/".format(HOST)
param = {
"login": "test<em>user",
"name": "test</em>user",
"phone": "00000",
"email": "xxx@test.com",
}</p>
<pre><code>res = requests.post(
base_url,
data=json.dumps(param),
headers=headers,
cookies={"session_id": get_session_id()},
)
print(res.json())
</code></pre>
<p>def edit<em>user():
base</em>url = "{}/api/users/3/".format(HOST)
param = {
"phone": "0000000000",
}</p>
<pre><code>res = requests.patch(
base_url,
data=json.dumps(param),
headers=headers,
cookies={"session_id": get_session_id()},
)
print(res.json())
</code></pre>
<p>if <strong>name</strong> == "<strong>main</strong>":
get<em>users()
# get</em>user()
# add<em>user()
# edit</em>user()</p>
<p>```</p>
<p>odoo 整個流程是要先取得 <code>session_id</code>(對 <code>/web/session/authenticate/</code> 發送請求),</p>
<p>( 請輸入正確的 db, login, password, host )</p>
<p>再去發送對應的 api ( 這邊都是使用 <code>jsonrpc</code> 的方式 ),</p>
<p>因為 <code>auth="user"</code> 就是去認你的 <code>session_id</code>.</p>