Tài liệu Odoo tốt, nhưng luôn đi sau và không bao giờ đủ chi tiết. May mắn là bạn có một tài liệu luôn đúng, luôn cập nhật, đầy đủ 100%: chính mã nguồn core — 693 module Python mà Odoo viết sẵn, nằm ngay trong máy bạn. Biết đọc nó là kỹ năng tăng tốc mạnh nhất của một lập trình viên Odoo. Sau khi đã biết đọc log, đây là bước tiếp theo.

Code core nằm ở đâu?

Trong container odoo19 (cài từ gói), toàn bộ mã nguồn nằm ở /usr/lib/python3/dist-packages/odoo/. Thư mục addons/ chứa 693 module:

docker exec odoo19 ls /usr/lib/python3/dist-packages/odoo/addons/ | wc -l
# 693

Mỗi module là một thư mục theo đúng cấu trúc bạn đã học: __manifest__.py, models/, views/, data/, controllers/, report/, i18n/. Module sale (Bán hàng) chẳng hạn có 69 file .py. Đây chính là kho ví dụ mẫu mực — cách Odoo tự làm mọi thứ.

Grep là la bàn của bạn

Đừng đọc tuần tự. Kỹ thuật cốt lõi là grep có mục tiêu — nhảy thẳng tới chỗ cần:

Bốn kỹ thuật điều hướng code core Odoo 19 bằng grep: code core có 693 module đếm bằng ls và wc; một là tìm model định nghĩa ở đâu bằng grep theo _name bằng sale.order ra file sale_order.py dòng 35; hai là tìm ai mở rộng model bằng grep theo _inherit bằng res.partner đếm được 103 module; ba là tìm một hàm hay action bằng grep def action_confirm; bốn là tìm một chuỗi hiện trên giao diện bằng grep chuỗi Confirmation Date trong thư mục addons sale

Hình 1: Bốn câu grep giải quyết 90% nhu cầu điều hướng. Chú ý cách #2: một câu grep -rln "_inherit = 'res.partner'" cho biết 103 module core cùng cắm thêm trường/hàm vào res.partner — bức tranh mà không tài liệu nào vẽ ra cho bạn.

Bốn mẫu grep đáng thuộc lòng:

CORE=/usr/lib/python3/dist-packages/odoo/addons

# 1) Model X định nghĩa ở đâu?
grep -rn "_name = 'sale.order'" $CORE/

# 2) Ai KẾ THỪA / mở rộng model X?
grep -rln "_inherit = 'res.partner'" $CORE/

# 3) Một hàm/action tên lạ đến từ đâu?
grep -rn "def action_confirm" $CORE/sale/

# 4) Một chuỗi hiện trên UI nằm ở file nào?
grep -rn "Confirmation Date" $CORE/sale/

Cách #4 cực hữu ích: thấy một nhãn lạ trên màn hình, grep đúng chuỗi đó là ra ngay file định nghĩa.

Đọc gì trong một model?

Mở một file model, 20 dòng đầu thường đã kể hết câu chuyện. Đây là đầu file thật sale_order.py:

Ảnh chụp code core thật của file addons sale models sale_order.py: class SaleOrder kế thừa models.Model; _name bằng sale.order; _inherit là danh sách gồm portal.mixin, product.catalog.mixin, mail.thread, mail.activity.mixin, utm.mixin; _description Sales Order; _order sắp theo date_order desc id desc; _check_company_auto True; _mail_post_access read; một ràng buộc SQL cấp cơ sở dữ liệu tên _date_order_conditional_required dùng models.Constraint với biểu thức CHECK; và một property _rec_names_search trả về danh sách tên trường tìm kiếm

Hình 2: Đầu file sale.order thật. Chỉ nhìn phần "khai báo" đã biết: model kế thừa các mixin nào (mail.thread cho khung chat, portal.mixin cho cổng khách hàng...), sắp xếp mặc định (_order), và ràng buộc dữ liệu (models.Constraint sinh một CHECK ở CSDL). Những dòng bắt đầu bằng _ là thuộc tính model — bản khai lý lịch của bảng.

Thứ tự đọc tôi hay dùng: (1) các thuộc tính _name, _inherit, _order; (2) các trường (fields.*) để biết bảng có gì; (3) các method action_*, _compute_*, write/create được override.

Vì sao đọc core lại học nhanh?

  • Luôn đúng: code là sự thật, tài liệu chỉ là mô tả. Khi chúng lệch nhau, tin code.
  • Là khuôn mẫu tốt nhất: muốn viết report, wizard, controller? Tìm một module core làm điều tương tự rồi bắt chước. Code Odoo có phong cách nhất quán.
  • Hiểu để mở rộng: muốn _inherit một model để thêm trường, bạn phải biết model gốc có gì — grep là cách nhanh nhất.

Mẹo thực dụng

  • Copy code core ra máy host để đọc bằng IDE có nhảy-định-nghĩa: docker cp odoo19:/usr/lib/python3/dist-packages/odoo/addons ./odoo-core.
  • Hoặc clone thẳng repo odoo/odoo nhánh 19.0 trên GitHub — cùng nội dung, tiện tra cứu lịch sử.
  • Khi lạc, quay về grep -rn với đúng chuỗi bạn thấy trên UI hoặc trong log.

Nhớ ba ý

  1. Toàn bộ code core (693 module) nằm sẵn trong container tại .../odoo/addons/ — kho ví dụ mẫu mực và là tài liệu luôn đúng.
  2. Điều hướng bằng grep có mục tiêu: tìm model theo _name, tìm người mở rộng theo _inherit, tìm nguồn của một nhãn UI theo chính chuỗi đó.
  3. Trong một model, đọc 20 dòng đầu (thuộc tính _) trước, rồi tới trường, rồi tới method — thứ tự đó cho bức tranh nhanh nhất.

Đọc và học từ core rồi, đã đến lúc bạn viết code của riêng mình một cách chuyên nghiệp — với quản lý phiên bản. Phần sau bàn về quy trình Git cho một module Odoo: cấu trúc repo, .gitignore, và cách versioning module cho gọn gàng.