Bạn để ý một menu Odoo mở ra đã lọc sẵn "chỉ đơn của tôi", một menu khác bấm Mới là form đã điền sẵn vài ô. Không có JavaScript nào phía sau, cũng không phải view đặc biệt. Tất cả nằm ở hai trường của chính cái ir.actions.act_window đứng sau menu đó: domain và context. Bài này dựng một action "Thẻ đang hiệu lực" dùng cả hai để thấy rõ mỗi cái làm gì.

Hai trường, hai nhiệm vụ khác nhau

domain lọc danh sách bản ghi được thấy. context mang thông tin đi kèm — trong đó hai khoá đặc biệt hữu ích: default_X (điền sẵn field khi tạo bản ghi mới) và search_default_X (bật sẵn một bộ lọc hoặc nhóm khi mở):

Ảnh chụp đoạn mã XML nền tối khai record ir.actions.act_window id action_the_dang_dung, field name Thẻ đang hiệu lực, res_model quan.the.thanh.vien, view_mode list phẩy form, field domain chứa list một tuple trang_thai bằng dang_dung với chú thích chỉ hiện bản ghi khớp list rút còn 2 trên 4, field context là dict gồm default_hang_the bằng vang với chú thích thẻ mới mặc định hạng Vàng, default_trang_thai bằng dang_dung, default_nhan_km bằng True, và search_default_gb_hang bằng 1 với chú thích mở là nhóm sẵn theo hạng, dưới cùng chú thích domain là list tuple bộ lọc còn context là dict default và search_default

Hình 1: Action "Thẻ đang hiệu lực". domain=[('trang_thai','=','dang_dung')] là một list tuple điều kiện — chỉ những thẻ đang dùng lọt qua. context là một dict: mỗi khoá default_<field> điền sẵn giá trị đó khi tạo mới, còn search_default_<tên> bật sẵn một filter/groupby đã khai trong search view. Cả hai đều là biểu thức được eval, nên viết đúng cú pháp Python.

domain — danh sách rút gọn ngay khi mở

Toàn hệ thống có 4 thẻ, nhưng mở menu này chỉ thấy 2 — đúng số thẻ dang_dung:

Ảnh chụp giao diện Odoo danh sách Thẻ đang hiệu lực, góc phải trên ghi 1-2 trên 2 nghĩa là chỉ hai bản ghi, ô tìm kiếm có sẵn chip nhóm Hạng thẻ, bảng nhóm theo hạng hiện Bạc mở ngoặc 1 và Vàng mở ngoặc 1 mỗi nhóm 150 điểm tổng 300, khung tìm kiếm bên trái liệt kê HẠNG THẺ với Tất cả Bạc 1 Vàng 1 và TRẠNG THÁI chỉ có Đang dùng 2

Hình 2: Cùng model, nhưng action này chỉ hiện 2/4 thẻ — hai thẻ hết hạn và bị khoá bị domain lọc ra. Góc phải ghi "1-2 / 2". Đồng thời danh sách đã nhóm sẵn theo Hạng thẻ nhờ search_default_gb_hang=1 — không cần người dùng tự bấm nhóm. Bảng tìm kiếm bên trái cũng chỉ còn thấy trạng thái "Đang dùng" vì domain đã giới hạn phạm vi.

Điểm quan trọng: domain của action là hàng rào cứng ở tầng này — người dùng gõ tìm kiếm thêm cũng chỉ tìm trong phạm vi đó, không thể "thoát" ra thấy thẻ khoá. Khác với record rule (bảo mật theo dòng), domain của action chỉ là lối vào tiện lợi, không phải cơ chế an ninh — ai có action khác vẫn xem được các thẻ kia.

context — điền sẵn khi bấm Mới

Bấm Mới trong chính action đó, form hiện ra đã được điền theo các default_X:

Ảnh chụp form tạo thẻ mới trong action Thẻ đang hiệu lực, thanh breadcrumb ghi TV-2026-### kèm chữ Vàng trong ngoặc vuông, thanh trạng thái phía trên phải sáng ở bước Đang dùng, ô Hạng thẻ hiển thị Vàng, ô Ghi chú nội bộ có placeholder Chỉ thẻ Vàng mới hiện ô này, các tab Lịch sử điểm Ghi chú Ưu đãi ở dưới

Hình 3: Form tạo mới mở từ action này — Hạng thẻ đã là "Vàng" (default_hang_the='vang'), trạng thái đã ở "Đang dùng" (default_trang_thai='dang_dung', thấy ở statusbar), và default_nhan_km=True bật sẵn nhận tin. Người dùng chỉ việc gõ nốt phần còn lại. Tên tạm "TV-2026-### [Vàng]" cũng phản ánh hạng mặc định.

Điều đáng nói: các default_X này chảy vào form qua context, và context của action truyền tiếp xuống mọi thao tác mở từ đó. Nên nếu form có nút tạo bản ghi liên quan, context (kể cả default_) vẫn đi theo — đôi khi gây điền sẵn ngoài ý muốn ở chỗ không mong đợi. Đó là mặt trái cần nhớ.

Vài lưu ý khi dùng

  • domain là list tuple, context là dict — cả hai lưu dạng chuỗi và được eval. Viết sai dấu ngoặc là action không mở được.
  • default_<field> phải đúng tên kỹ thuật của field, và giá trị đúng kiểu: Selection truyền mã ('vang' không phải 'Vàng'), Boolean truyền True/False, Many2one truyền id.
  • search_default_<name>: name là tên của <filter> hoặc <field>/groupby đã khai trong search view. Gán 1 để bật; sai tên thì im lặng không có tác dụng.
  • Context còn nhận biến động: active_id, active_ids, uid có sẵn; và bạn có thể dùng {'default_partner_id': active_id} để điền sẵn theo bản ghi đang mở (hay gặp ở nút thông minh).

Ba ý mang về

  1. domain lọc sẵn danh sách ngay khi mở action (list rút còn 2/4) — tiện lối vào, nhưng không phải bảo mật (đó là việc của record rule).
  2. context với default_X điền sẵn field khi tạo mới, search_default_X bật sẵn filter/groupby khi mở — biến một menu chung thành lối làm việc chuyên biệt mà không cần view riêng.
  3. Cú pháp phải chuẩn: domain là list tuple, context là dict, tên field/filter phải đúng — sai thì hoặc lỗi mở, hoặc lặng lẽ vô tác dụng.

Action mới chỉ mở một danh sách. Nhưng có loại action chạy thẳng trên nhiều bản ghi bạn tick chọn — xoá hàng loạt, đổi trạng thái cả lô. Phần sau đi vào action chạy trên nhiều bản ghi qua menu ⚙ Tác vụ, và cách nhận active_ids.