Controller trong Odoo
Tut 5: Odoo Controller
Trước khi xem bài viết này, bạn vui lòng hoàn thành hướng dẫn ở Tut 4 hoặc download mã nguồn ở cuối bài Tut 4. Bài viết này sẽ hướng dẫn bạn cách tạo mới một controller trong Odoo.
Mã nguồn hoàn chỉnh cho bài viết này được đính kèm ở cuối bài viết.
Tạo controller trong Odoo
Khai báo controller
Đầu tiên, ta tạo một thư mục controllers bên trong module mypet và trong đó chứa 2 file mới là __init__.py và main.py. Cấu trúc như sau:
mypet/controllers:
- __init__.py
- main.py
Đồng thời, ta phải khai báo trong file init để nó biết sự tồn tại của code Python trong controllers folder vừa tạo.
mypet/__init__.py:
from . import models
from . import controllers # <- them dong nay
Hiện thực Odoo controller
Trước khi hiện thực main.py, ta phải import code python này cái đã, bằng cách thêm dòng sau vào file init.
mypet/controllers/__init__.py:
from . import main
Rồi, đến đây là ta import xong xuôi các thủ tục "quy trình" cần thiết.
API đầu tiên - foo API
Main controller ta hiện thực như sau:
- Khai báo class của chúng ta MyPetAPI kế thừa Odoo controller là http.Controller
- Routing đường dẫn đến method mà sẽ đón nhận xử lý: route @ /foo -> foo_handler()
- Trong hàm foo ta trả về chuỗi chào mừng. Bất kể bạn có đăng nhập vào Odoo hay không, vì ta đã đặc tả auth là public
- Các thuộc tính của route() tham khảo thêm tại đây: https://www.odoo.com/documentation/13.0/reference/http.html#odoo.http.route
mypet/controllers/main.py:
import odoo
import logging
_logger = logging.getLogger(__name__)
class MyPetAPI(odoo.http.Controller):
@odoo.http.route('/foo', auth='public')
def foo_handler(self):
return "Welcome to 'foo' API!"
Sau khi hiện thực API foo xong, ta restart Odoo server. Nếu bạn đang dùng docker-compose trên web Minh đã chỉ dẫn thì không cần restart vì bên trong đã thêm cờ tự động restart nếu code Python thay đổi.
Xem thành quả bằng cách mở trình duyệt tại localhost:10013/foo
, được kết quả như hình dưới:
JSON API - bar API
Giờ ta muốn viết một bar API trả về dữ liệu dạng chuỗi json, để client có thể parse và xử lý ở frontend. Ta cần thêm vào main.py như sau:
mypet/controllers/main.py
...
import json
...
class MyPetAPI(odoo.http.Controller):
...
@odoo.http.route('/bar', auth='public')
def bar_handler(self):
return json.dumps({
"content": "Welcome to 'bar' API!"
})
Mở trình duyệt tại localhost:10013/bar
được kết quả:
{"content": "Welcome to 'bar' API!"}
API đọc dữ liệu từ Model
API này bặt đầu phức tạp hơn, ta muốn tạo một public API trả về thông tin của Pet. Như vậy controller của ta phải đón nhận được dẫn routing theo dạng /pet/<DBNAME>/<ID>
, sau đó truy vấn model theo database name đọc ra dữ liệu và trả về chuỗi json. Ta sẽ tiến hành hiện thực theo code bên dưới:
mypet/controllers/main.py
... # import nhu tren
class MyPetAPI(odoo.http.Controller):
... # code nhu tren
@odoo.http.route(['/pet/<dbname>/<id>'], type='http', auth="none", sitemap=False, cors='*', csrf=False)
def pet_handler(self, dbname, id, **kw):
model_name = "my.pet"
try:
registry = odoo.modules.registry.Registry(dbname)
with odoo.api.Environment.manage(), registry.cursor() as cr:
env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {})
rec = env[model_name].search([('id', '=', int(id))], limit=1)
response = {
"status": "ok",
"content": {
"name": rec.name,
"nickname": rec.nickname,
"description": rec.description,
"age": rec.age,
"weight": rec.weight,
"dob": rec.dob.strftime('%d/%m/%Y'),
"gender": rec.gender,
}
}
except Exception:
response = {
"status": "error",
"content": "not found"
}
return json.dumps(response)
Giải thích:
- Ta cần tham số dbname là bởi vì Odoo server cho phép tạo nhiều database, và mỗi database có một tên duy nhất không trùng nhau. Mình có thể kiểm tra tên database bằng cách mở chế độ debug lên, tên db sẽ ở cạnh tên user đang đăng nhập.
- Trong phương thức pet_handler() ta mở môi trường kết nối đến bảng "my.pet" bằng account admin odoo.SUPERUSER_ID để tìm kiếm và đọc ra dữ liệu.
- Trường hợp nếu có bất kỳ lỗi nào (exception) ta sẽ trả về response lỗi không tìm thấy.
- Dữ liệu trả về sẽ bị lỗi nếu có Object trong đó, cụ thể trong ví dụ trên thì là trường rec.dob (ngày sinh của thú cưng), nó sẽ là DateTime object chẳng hạn, do đó ta phải chuyển đổi sang dạng string để tránh lỗi, sẵn tiện format luôn theo định dạng ngày/tháng/năm ta mong muốn.
Thử kiếm tra lại API mới viết xem sao:
Minh đã tạo database tên là tut5 (nhớ đổi lại theo tên database name của bạn đang thực hành trên máy), và tạo 1 record đầu tiên trên giao diện của module mypet (tut 4). Sau đó truy vấn theo URL sau:
$ curl http://localhost:10013/pet/tut5/1
{"status": "ok", "content": {"name": "Cat named Dog", "nickname": "Kyz", "description": "Pick from the street", "age": 1, "weight": 8.0, "dob": "08/01/2020", "gender": "male"}}
$ curl http://localhost:10013/pet/tut5/0
{"status": "error", "content": "not found"}
$ curl http://localhost:10013/pet/noexist_db/1
{"status": "error", "content": "not found"}
Download Tut 5 - Odoo Controller
Source code download: Tut 5 - Controller
Chuyên mục thảo luận cho Tut 5 @ https://www.facebook.com/groups/odoo.dev/learning_content/?filter=226430075118574&post=899424217189282
- Khóa học lập trình Odoo TP.HCM: Thông tin và đăng ký khóa học
- Khảo sát nhu cầu học nghiệp vụ Odoo Offline @ HCM & đăng ký sớm: https://forms.gle/auBXLNbfuNqhJSbj8
Cài đặt Odoo:
- Docker Compose for Odoo 10
- Docker Compose for Odoo 11
- Docker Compose for Odoo 12
- Docker Compose for Odoo 13
- Docker Compose for Odoo 14
- Docker Compose for Odoo 15
- Docker Compose for Odoo 16
Danh sách bài viết series Odoo:
- Tut 0: Học lập trình Odoo - tutorials
- Tut 1: Odoo là gì?
- Tut 2: Hướng dẫn cài đặt Odoo version 10, 11, 12, 13
- Tut 3: Tạo model trong Odoo
- Tut 4: View trong Odoo
- Tut 5: Controller trong Odoo
- Tut 6: Thừa kế model trong Odoo
- Tut 7: Thừa kế view trong Odoo
- Tut 8: Thừa kế controller trong Odoo
- Tut 9: API trong Odoo - XML-RPC
- Tut 10: Hiện thực wizard trong Odoo
- Tut 11: Tạo widget trong Odoo
- Tut 12: Tạo settings trong Odoo cho custom addon
- Tut 13: Thêm button cho list/tree view trong Odoo
- Tut 14: Search, Filter, Group By trong Odoo
- Tut 15: Kết nối PostgreSQL database của Odoo bằng câu lệnh
- Tut 16: Kết nối pgAdmin vào PostgreSQL database của Odoo
Tham gia ngay group trên Facebook để cùng thảo luận với đồng bọn nhé:
- Fanpage Minh: https://www.facebook.com/minhng.info
- Khám phá Odoo: https://www.facebook.com/groups/odoo-dev
Khám phá Odoo