Bạn có một One2many trong form — chẳng hạn "lịch sử điểm" của một thẻ thành viên. Mặc định, mỗi lần muốn thêm một dòng, Odoo bật một form con (dialog) lên, bạn điền, bấm Lưu, dialog đóng. Nhập ba dòng là ba lần mở–đóng. Với dữ liệu dạng bảng, kiểu nhập đó chậm phát bực. editable là thứ đổi hẳn trải nghiệm: cho gõ thẳng trên từng dòng của bảng, như điền một cái spreadsheet.
Một thuộc tính, đổi cả cách nhập
Chỉ cần thêm editable vào thẻ <list> bên trong One2many. Đây là đúng đoạn đang chạy trong module demo quan_ca_phe, cho field lich_su_ids ở tab "Lịch sử điểm":

Hình 1: Khối trên là bản thật trong module — <list editable="bottom"> đủ để cả bảng con nhập được trực tiếp. Khối dưới là mẫu cú pháp Odoo 19 cho các thuộc tính điều khiển từng cột (không phải bản đang cài, chỉ minh hoạ). Chú ý column_invisible — của Odoo 19, thay cho kiểu attrs cũ.
editable nhận hai giá trị:
editable="top"— dòng thêm mới xuất hiện ở đầu bảng.editable="bottom"— dòng mới nằm ở cuối bảng (hợp với lịch sử tăng dần theo thời gian, nên demo dùng cái này).
Không có editable, cùng cái <list> đó vẫn hiển thị danh sách, nhưng bấm vào dòng sẽ mở form con. Có editable, bấm vào ô là con trỏ nhảy vào đó luôn.
Nhìn nó chạy thật
Mở một thẻ thành viên (VIP-0001), sang tab "Lịch sử điểm", rồi bấm vào ô "Ghi chú" của một dòng:

Hình 2: Bấm vào ô "Ghi chú" của dòng đầu — cả dòng sáng lên (đang chọn) và ô chuyển thành ô nhập, gõ sửa được ngay tại chỗ. Không có dialog nào bật lên. Cuối bảng là link "Thêm một dòng": bấm vào để chèn một dòng trống rồi nhập tiếp — với editable="bottom" nó nằm ở cuối như thế này.
Cái hay là toàn bộ thao tác nằm trên cùng một màn hình: bấm ô này xong tab sang ô kia, Enter để xuống dòng dưới. Nhập một loạt dòng liền mạch, không lần nào rời form cha.
Điều khiển từng cột
Vì mỗi cột là một <field>, bạn đặt được thuộc tính lên từng ô — và trong Odoo 19 các biểu thức viết thẳng, không bọc trong attrs={...} như bản cũ:
<list editable="bottom">
<field name="ngay" required="1"/>
<field name="diem_cong" readonly="trang_thai == 'huy'"/>
<field name="ghi_chu" column_invisible="parent.an_ghi_chu"/>
</list>
required="1"— ô bắt buộc nhập; để trống mà lưu là Odoo chặn ngay trên dòng.readonly="<biểu thức>"— khoá ô theo điều kiện tính trên chính dòng đó.column_invisible="<biểu thức>"— ẩn cả cột. Đây là điểm khác biệt quan trọng của list so với form: muốn ẩn nguyên cột thì dùngcolumn_invisible, còninvisiblechỉ ẩn ô trên một dòng.parent.cho phép đọc field của form cha để quyết định.
Biểu thức là Python thuần, chạy trên dữ liệu của dòng (và parent. cho form cha), nên bạn diễn đạt được những quy tắc kiểu "cột điểm khoá lại khi thẻ đã huỷ" mà không cần một dòng JavaScript nào.
onchange chạy ngay khi gõ
Điểm mạnh thật sự của editable list: onchange trên model của dòng chạy ngay lúc bạn sửa một ô, chưa cần lưu. Ví dụ, nếu model quan.lich.su.diem có một @api.onchange('diem_cong') để cảnh báo khi điểm cộng âm, thì vừa gõ số âm là cảnh báo hiện — ngay trên dòng đang nhập. Với form con thì bạn phải mở dialog mới thấy; với editable list, phản hồi tức thì tại chỗ.
Cùng cơ chế đó cho phép cột tính toán cập nhật sống: gõ số lượng, thành tiền tự nhảy — đây chính là cách các dòng chi tiết đơn hàng, hoá đơn của Odoo hoạt động.
Khi nào nên bật editable
- One2many là dòng chi tiết (lịch sử, dòng đơn, bảng công) → gần như luôn nên
editable. Người dùng nhập nhanh hơn hẳn. - One2many trỏ tới bản ghi nặng, nhiều field → giữ form con (dialog) lại hơn, vì nhồi hết vào một dòng bảng sẽ chật và khó đọc.
- List độc lập ở cấp cao nhất (một action mở thẳng ra danh sách) cũng đặt
editableđược, cho sửa nhanh không cần vào form — nhưng cân nhắc, vì sửa nhầm trên bảng dễ hơn.
Ba ý mang về
editable="top"/editable="bottom"biến<list>trong One2many thành nơi nhập trực tiếp — bấm ô là sửa, không mở form con;top/bottomquyết định dòng mới nằm ở đầu hay cuối.- Điều khiển từng cột bằng thuộc tính viết thẳng (Odoo 19):
required,readonly="<expr>", và đặc biệtcolumn_invisibleđể ẩn nguyên cột (khácinvisiblechỉ ẩn một ô).parent.đọc được form cha. onchangecủa model dòng chạy ngay khi gõ, cho phản hồi và cột tính toán cập nhật tức thì — thứ khiến các dòng chi tiết đơn hàng/hoá đơn của Odoo mượt như vậy.
Editable list cho ta nhập gọn trên một bảng. Nhưng khi form phình to với hàng chục field, ta cần chia nó cho dễ thở. Phần sau nói về notebook và page — cách gom field thành các tab trong form.