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:

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:

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
_inheritmộ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/odoonhánh19.0trên GitHub — cùng nội dung, tiện tra cứu lịch sử. - Khi lạc, quay về
grep -rnvới đúng chuỗi bạn thấy trên UI hoặc trong log.
Nhớ ba ý
- 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. - Đ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 đó. - 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.