Lỗi kinh điển của người mới viết module: đặt thư mục module vào máy chủ, khởi động Odoo, vào Ứng dụng tìm mãi không thấy. Nguyên nhân gần như luôn là không hiểu Odoo tìm module ở đâu và bằng cách nào. Bài này mổ xẻ đúng cơ chế đó — tham số addons_path và quy trình quét.
Odoo quét những đâu?
Odoo gom hai nguồn thành danh sách nơi chứa module:

Hình 1: Quy trình quét. Thư mục addons lõi của chính Odoo luôn được quét (đây là lý do module đặt trong đó cũng được thấy). Cộng với mọi thư mục khai trong addons_path. Với mỗi thư mục con, Odoo hỏi một câu duy nhất: có tệp __manifest__.py không? — Có thì đây là một module, đọc manifest và ghi một dòng vào bảng ir.module.module; Không thì bỏ qua như thư mục thường.
Ba điểm dễ vấp:
addons_pathchỉ là danh sách thư mục CHA, không phải trỏ thẳng vào module. Trỏ/opt/customthì module nằm ở/opt/custom/ten_module/.- Thư mục addons lõi luôn được thêm dù không khai — nên module đặt cạnh app gốc cũng chạy (nhưng đừng làm vậy ở production).
- Nhận diện bằng
__manifest__.py— thiếu file này, Odoo coi thư mục là rác và bỏ qua (module "vô hình").
Kiểm chứng trên máy chủ thật
Đây là số liệu thật của máy chủ Odoo 19 loạt bài này:

Hình 2: Kiểm thật. addons_path khai /mnt/extra-addons, nhưng thư mục addons lõi có 693 module vẫn được quét (luôn luôn). Trong odoo shell, đếm được 714 module Odoo nhận diện (đã cài + chưa cài) — nhiều hơn 693 vì gộp thêm các nguồn khác. Và module tự viết quan_ca_phe ở trạng thái installed. Con số 714 chính là số dòng trong bảng ir.module.module.
"Cập nhật danh sách phân hệ" làm gì?
Khi bạn thêm một module mới vào addons_path lúc Odoo đang chạy, nó chưa xuất hiện ngay — vì danh sách module (ir.module.module) chỉ quét lúc khởi động hoặc khi bạn bấm Cập nhật danh sách phân hệ (Update Apps List) trong màn Ứng dụng (cần Chế độ nhà phát triển).
Thao tác đó quét lại mọi thư mục, và thêm dòng mới (state uninstalled) cho module chưa có trong bảng. Sau đó bạn mới thấy nó để bấm Kích hoạt.
Tương đương dòng lệnh: khởi động với
-u base(hoặc bất kỳ, kèm việc quét), hay đơn giản-i ten_module— Odoo tự quét trước khi cài.
Thứ tự trong addons_path: ai thắng khi trùng tên?
Nếu hai thư mục trong addons_path cùng chứa module trùng tên (ví dụ bạn muốn ghi đè một module lõi bằng bản sửa của mình), Odoo dùng module ở thư mục đứng TRƯỚC trong danh sách. Đây là kỹ thuật ghi đè: đặt custom-addons trước đường dẫn addons lõi.
Nhưng cẩn thận: ghi đè cả module bằng cách trùng tên rất dễ gây rối — thường kế thừa (_inherit) là cách sạch hơn, sẽ nói ở bài riêng.
Vài lưu ý thực dụng
- Đường dẫn tuyệt đối trong
addons_path, ngăn nhau bằng dấu phẩy, không có khoảng trắng thừa. - Quyền đọc: tiến trình Odoo phải đọc được thư mục module — lỗi quyền cũng làm module "vô hình".
- Sau khi thêm module: bấm Cập nhật danh sách phân hệ (hoặc khởi động lại) rồi mới thấy.
- Đừng để rác trong addons_path: mọi thư mục có
__manifest__.pyđều bị coi là module và cố nạp.
Nhớ ba ý
- Odoo quét thư mục addons lõi (luôn) + mọi thư mục trong
addons_path; mỗi thư mục con có__manifest__.pythì là một module, ghi vàoir.module.module. - Module mới thêm phải Cập nhật danh sách phân hệ (hoặc khởi động lại) mới hiện;
addons_pathtrỏ thư mục cha, không trỏ thẳng module. - Trùng tên thì thư mục đứng trước trong addons_path thắng — kỹ thuật ghi đè, nhưng thường
_inheritsạch hơn.
Ở dev, sửa code rồi phải khởi động lại hoài rất mệt. Phần sau đào sâu chế độ --dev: auto-reload Python, làm mới assets, và các cờ debug giúp bạn code nhanh hơn hẳn.