Ở bài trước ta thấy: thêm module mới phải khởi động lại Odoo nó mới nhận. Khi đang code, bạn sửa file liên tục — chẳng lẽ mỗi lần lại Ctrl+C rồi gõ lại lệnh khởi động? Odoo có sẵn lời giải: cờ --dev. Bài này mổ xẻ đúng nó làm gì, dựa trên mã nguồn thật của Odoo 19.

--dev không phải một công tắc, mà là sáu

Nhiều người tưởng --dev bật/tắt "chế độ dev". Thật ra nó nhận một danh sách tính năng ngăn nhau bằng dấu phẩy:

Bảng sáu tính năng của cờ dev trong Odoo 19: reload khởi động lại server khi mã nguồn .py đổi, xml đọc view thẳng từ file XML không lấy từ CSDL, qweb ghi log XML đã biên dịch khi QWeb lỗi, access ghi traceback đầy đủ khi lỗi phân quyền, werkzeug mở trình gỡ lỗi HTML khi request HTTP lỗi, replica giả lập triển khai có bản sao chỉ đọc; kèm ví dụ lệnh odoo -d blog19 -u quan_ca_phe với dev bằng all

Hình 1: Sáu tính năng của --dev trong Odoo 19. Chú ý giá trị đặc biệt all — nó KHÔNG bằng cả sáu, mà chỉ gồm bốn: access,reload,qweb,xml. Hai cái còn lại (replica, werkzeug) phải bật tay vì chúng đổi hành vi khá mạnh.

Đây không phải tôi bịa: all được định nghĩa bằng một hằng số trong mã nguồn Odoo.

Bằng chứng từ mã nguồn, không phải tài liệu

Vì cả loạt bài này bám vào máy chủ thật, tôi mở thẳng mã nguồn Odoo 19 trong container để bạn thấy các tính năng này có thật và làm đúng như mô tả:

Terminal thật trong container odoo19: odoo version 19.0-20260908; grep ALL_DEV_MODE trong server.py ra dòng 29 ALL_DEV_MODE bằng danh sách access qweb reload xml; đoạn class FSWatcherBase cho thấy khi file .py đổi thì compile kiểm cú pháp rồi ghi log autoreload python code updated và gọi restart; dòng Watching addons folder theo dõi mọi thư mục addons; ir_ui_view.py dòng 225 kiểm xml in config dev_mode để đọc view từ file; import watchdog chạy ok

Hình 2: Bằng chứng thật. Hằng ALL_DEV_MODE ở dòng 29 của server.py xác nhận all gồm đúng bốn tính năng. Cơ chế reload: khi một file .py thay đổi, Odoo biên dịch thử để kiểm cú pháp trước, rồi mới restart() — nên lỗi cú pháp không làm sập server mà chỉ ghi log. watchdog có sẵn nên Odoo dùng Observer theo dõi mọi thư mục addons. Còn xml: ir_ui_view.py dòng 225 kiểm 'xml' in config['dev_mode'] để quyết định đọc view từ file hay từ CSDL.

Ba tính năng dùng nhiều nhất

reload — khỏi khởi động lại tay

Khi bật reload, Odoo chạy một luồng theo dõi hệ thống tệp (dùng thư viện watchdog). Bạn lưu một file .py, nó tự khởi động lại server. Quan trọng: nó compile thử file trước, nếu bạn lỡ để lỗi cú pháp thì nó chỉ ghi log SyntaxError chứ không restart vào trạng thái hỏng.

# Ở terminal chạy Odoo, sau khi sửa models/quan_the_thanh_vien.py:
# INFO ... autoreload: python code updated, autoreload activated
# → server tự nạp lại, không cần bạn làm gì

Lưu ý: reload chỉ bắt code Python. Sửa view XML thì reload không giúp — đó là việc của tính năng xml.

xml — sửa view khỏi cập nhật module

Bình thường Odoo lưu định nghĩa view trong CSDL (bảng ir_ui_view), nạp từ file XML lúc cài/nâng cấp module. Nên sửa file .xml mà không -u module thì giao diện không đổi.

Bật xml, Odoo đọc view thẳng từ file mỗi lần render (với view chưa bị sửa tay qua giao diện — điều kiện not view.arch_updated ở Hình 2). Nhờ vậy sửa XML, F5 là thấy ngay, khỏi nâng cấp module liên tục.

qweb / access / werkzeug — để debug

  • qweb: template QWeb lỗi thì log ra XML đã biên dịch, dễ soi lỗi hơn nhiều.
  • access: lỗi phân quyền in traceback đầy đủ, biết chính xác dòng nào chặn (xem lại record rules để hiểu vì sao hay gặp lỗi quyền).
  • werkzeug: request HTTP lỗi thì mở một trình gỡ lỗi HTML tương tác ngay trên trình duyệt. Mạnh nhưng chỉ nên bật ở máy dev — nó cho phép chạy code từ trình duyệt.

Lệnh dev tôi hay dùng

# Vừa đủ cho công việc thường ngày: reload code + đọc XML từ file + log qweb
odoo -d blog19 -u quan_ca_phe --dev=all --log-level=debug

# Tránh bị ngắt khi đang đặt breakpoint gỡ lỗi (bỏ giới hạn thời gian request)
odoo -d blog19 --dev=all --limit-time-real=0

--limit-time-real=0 đi kèm rất hợp: khi bạn dừng ở breakpoint (pdb) để soi biến, worker không bị "quá giờ" mà giết request đang treo.

Cảnh báo: chỉ dùng ở máy dev

--dev đánh đổi an toàn/hiệu năng lấy tiện lợi: đọc file mỗi request, mở debugger tương tác, log dài. Trên production tuyệt đối không bật — đặc biệt werkzeug là lỗ hổng thực thi code, còn xml/reload làm chậm và bất định. Production chạy Odoo trơn không cờ dev, và nâng cấp module một cách có kiểm soát.

Nhớ ba ý

  1. --dev nhận danh sách tính năng; all = access,reload,qweb,xml (KHÔNG gồm replica, werkzeug).
  2. reload tự khởi động lại khi sửa .py (compile thử trước, watchdog theo dõi addons); xml đọc view thẳng từ file — hết cảnh nâng cấp module liên tục.
  3. Cực tiện khi code nhưng chỉ ở máy dev; production không bao giờ bật cờ dev.

Giờ vòng lặp sửa–xem đã nhanh, ta cần một chỗ để nghịch trực tiếp với dữ liệu và ORM mà không cần viết cả module. Phần sau khám phá odoo shell — cửa sổ Python tương tác vào thẳng cơ sở dữ liệu Odoo.