Ở bài 195, model thẻ thành viên đã có list và form đẹp. Nhưng có một vấn đề: người dùng chưa có cách nào bấm vào để mở — ta phải gõ URL kỹ thuật. Cần thêm hai mảnh: action (bảo Odoo "mở cái gì") và menu (chỗ để bấm). Xong hai thứ này, model của bạn thành một app có menu riêng trên thanh ứng dụng, ngang hàng Bán hàng, Tồn kho.

Action và menu: hai khái niệm bổ trợ

  • Action (ir.actions.act_window): định nghĩa "khi kích hoạt thì mở model nào, ở dạng view nào". Nó là hành động, chưa phải chỗ bấm.
  • Menu (menuitem): một mục menu người dùng thấy và bấm; khi bấm, nó chạy một action.

Ta khai cả hai trong views/menus.xml:

Mã nguồn XML file menus.xml: một record action_the_thanh_vien model ir.actions.act_window với name Thẻ thành viên, res_model quan.the.thanh.vien, view_mode list,form, help; một menuitem menu_quan_ca_phe_root name Quán Cà Phê sequence 90; và menuitem con menu_the_thanh_vien name Thẻ thành viên parent menu gốc action trỏ action_the_thanh_vien

Hình 1: File menus.xml. Window action action_the_thanh_vien: mở model quan.the.thanh.vien ở view_mode list,form (vào là thấy danh sách, bấm một dòng ra biểu mẫu). Rồi hai menuitem: một menu gốc "Quán Cà Phê" (thành một app trên thanh trên), và một menu con "Thẻ thành viên" (parent trỏ menu gốc, action trỏ tới action vừa khai). sequence quyết định thứ tự sắp xếp.

Đừng quên khai file này vào data của __manifest__.py — không thì Odoo bỏ qua nó khi cài.

Cài vào Odoo — app xuất hiện trên thanh trên

Sau khi cập nhật module, một app mới hiện lên với menu con dẫn thẳng vào danh sách:

Giao diện Odoo hiển thị app Quán Cà Phê trên thanh trên cùng với menu con Thẻ thành viên; nội dung là danh sách Thẻ thành viên với dòng VIP-0001 của Nguyễn Văn An 120 điểm

Hình 2: App "Quán Cà Phê" giờ nằm trên thanh trên cùng (menu gốc), với mục con "Thẻ thành viên". Bấm vào, Odoo chạy action → mở đúng danh sách Thẻ thành viên đã dựng ở bài 195. Từ một model Python, qua vài dòng XML, ta có một app hoàn chỉnh có lối vào rõ ràng — y như các app gốc của Odoo.

Ghép lại toàn bộ chuỗi

Nhìn lại bốn bài lập trình vừa qua, ta thấy Odoo lắp ghép rất mạch lạc:

  1. Module (__manifest__.py) — khung chứa mọi thứ.
  2. Model (Python) — dữ liệu, tự tạo bảng.
  3. View (XML) — cách hiển thị (list, form).
  4. Action + Menu (XML) — lối vào cho người dùng.

Mỗi mảnh một việc, ghép lại thành một tính năng hoàn chỉnh. Đây chính là "giải phẫu" của bất kỳ app Odoo nào — kể cả Bán hàng, Kho: chỉ là quy mô lớn hơn.

Lưu ý khi làm action & menu

  • Menu gốc không cần action (nó chỉ là nhóm); menu con mới trỏ action để có gì đó mở ra.
  • view_mode liệt kê thứ tự — list,form nghĩa vào thấy list trước. Muốn vào thẳng form thì form,list.
  • Khai file vào data của manifest và cập nhật module (-u) — quên là menu không hiện.
  • sequence để sắp xếp menu; số nhỏ lên trước.
  • Cần quyền truy cập thì người dùng mới thấy dữ liệu khi bấm menu — đúng chủ đề bài sau.

Nhớ ba ý

  1. Action (ir.actions.act_window) định nghĩa mở model nào, view nào; menuitem tạo chỗ bấm và chạy action đó.
  2. Menu gốc thành một app trên thanh trên; menu con (parent + action) là lối vào dữ liệu — nhớ khai file vào data của manifest.
  3. Chuỗi Module → Model → View → Action/Menu là giải phẫu chung của mọi app Odoo.

Menu đã mở ra danh sách, nhưng nếu người dùng không có quyền thì bấm vào sẽ báo lỗi. Phần sau ta khai quyền truy cập model qua ir.model.access.csv — cho ai được đọc/ghi/xoá dữ liệu.