Trạng thái đơn (nháp/xác nhận/hoàn thành), hạng thẻ (bạc/vàng/bạch kim), giới tính — những trường "chọn một trong vài giá trị cố định" dùng kiểu Selection. Nó đơn giản nhưng có một điểm quan trọng dễ sai (mã vs nhãn) và một tính năng ít người biết (lựa chọn động). Nối tiếp Command cho quan hệ, bài này bàn trường Selection.

Selection tĩnh: mã và nhãn

Cách phổ biến nhất: khai một list các cặp (mã, nhãn):

Trường Selection trong Odoo 19 danh sách lựa chọn tĩnh và động: tĩnh là list các cặp mã lưu cơ sở dữ liệu và nhãn hiển thị, hang_the bằng fields.Selection với list cặp bac Bạc, vang Vàng, bach_kim Bạch kim, default bac, cơ sở dữ liệu lưu bac còn giao diện hiện Bạc; động là truyền tên method sinh lựa chọn lúc chạy, trang_thai bằng fields.Selection với selection bằng chuỗi _selection_trang_thai không gọi ngoặc, default moi, decorator api.model def _selection_trang_thai self có thể truy vấn cơ sở dữ liệu hoặc tính lúc chạy để sinh lựa chọn return list cặp moi Mới cấp, dang_dung Đang dùng, het_han Hết hạn, khoa Đã khoá; tĩnh vs động, tĩnh lựa chọn cố định lúc khai phổ biến nhất, động sinh theo dữ liệu ngữ cảnh ví dụ đọc từ cấu hình từ model khác, cơ sở dữ liệu luôn lưu mã đổi nhãn không ảnh hưởng dữ liệu cũ

Hình 1: Selection tĩnh là list cặp ('mã', 'nhãn') — CSDL lưu mã ('bac'), giao diện hiện nhãn ('Bạc'). Selection động truyền tên method (chuỗi '_selection_trang_thai', không gọi ()) — method đó sinh danh sách lựa chọn lúc chạy, cho phép truy vấn CSDL hay tính theo ngữ cảnh.

Cả hai kiểu chạy thật

Tôi thêm một field trang_thai Selection động bên cạnh hang_the tĩnh sẵn có, nâng cấp, rồi kiểm. Output thật trên db blog19:

Selection tĩnh và động chạy thật trên module quan_ca_phe database blog19: tĩnh hang_the, T._fields hang_the chấm selection là list cặp cố định bac Bạc vang Vàng bach_kim Bạch kim; động trang_thai, type của T._fields trang_thai chấm selection chấm name là str tức chuỗi tên method resolve lúc chạy, T._selection_trang_thai gọi method sinh lựa chọn trả list cặp moi Mới cấp dang_dung Đang dùng het_han Hết hạn khoa Đã khoá; tạo thẻ với trạng thái dang_dung, the bằng T.create name SEL-001 trang_thai dang_dung, the.trang_thai trả dang_dung là cơ sở dữ liệu lưu mã, nhãn hiển thị trả Đang dùng là giao diện hiện nhãn

Hình 2: Output thật. hang_the.selection là một list cặp cố định. Còn trang_thai.selection là một chuỗi (str) — tên method; Odoo gọi _selection_trang_thai() lúc chạy để lấy danh sách. Khi tạo thẻ với trang_thai='dang_dung', CSDL lưu mã 'dang_dung', còn giao diện hiện nhãn 'Đang dùng'.

Điểm cốt lõi: CSDL lưu MÃ

Đây là điều phải nhớ nhất. Trường Selection lưu mã ('dang_dung'), không phải nhãn ('Đang dùng'). Hệ quả:

  • Đổi nhãn an toàn: sửa 'Đang dùng' thành 'Đang sử dụng' không đụng dữ liệu cũ — mã vẫn 'dang_dung'.
  • Đổi mã thì NGUY HIỂM: đổi 'dang_dung' thành 'active' làm mọi bản ghi cũ (lưu 'dang_dung') mồ côi — không khớp lựa chọn nào. Cần script migration.
  • Domain lọc theo mã: [('trang_thai', '=', 'dang_dung')], không phải nhãn.
  • So sánh trong code theo mã: if rec.trang_thai == 'khoa':.

Quy tắc: mã đặt một lần, giữ ổn định (chữ thường, không dấu, như biến); nhãn tự do đổi (có dấu, thân thiện người dùng).

Khi nào dùng Selection động?

Selection động (selection='_method') hữu ích khi lựa chọn không cố định lúc viết code:

@api.model
def _selection_quoc_gia_hay_dung(self):
    # Sinh lựa chọn từ dữ liệu thật lúc chạy
    countries = self.env['res.country'].search([('code', 'in', ['VN','US','JP'])])
    return [(c.code, c.name) for c in countries]

Hoặc lựa chọn phụ thuộc cấu hình, module đã cài, hay ngữ cảnh người dùng. Còn nếu lựa chọn cố định thì luôn dùng list tĩnh — đơn giản và nhanh hơn.

Selection vs Many2one

Dễ nhầm: khi nào Selection, khi nào Many2one?

  • Selection: vài lựa chọn cố định, do lập trình viên định (trạng thái, giới tính). Người dùng không thêm/sửa được.
  • Many2one: lựa chọn là bản ghi trong bảng khác, người dùng quản lý được (danh mục sản phẩm, quốc gia, khách hàng). Thêm/sửa/xoá qua giao diện.

Quy tắc: người dùng cần tự thêm lựa chọn → Many2one; lựa chọn bất biến trong code → Selection.

Nhớ ba ý

  1. Trường Selection là list cặp (mã, nhãn): CSDL lưu mã, giao diện hiện nhãn — đo thật: lưu 'dang_dung', hiện 'Đang dùng'.
  2. Đổi nhãn an toàn, đổi mã nguy hiểm (làm bản ghi cũ mồ côi); domain/so sánh luôn theo mã; động khai bằng tên method sinh lựa chọn lúc chạy.
  3. Lựa chọn cố định do code định → Selection; lựa chọn là bản ghi người dùng quản → Many2one.

Nói về giá trị đặc biệt, có một loại trường số dành riêng cho tiền. Phần sau đi vào trường Monetary — cách Odoo xử lý số tiền kèm đơn vị tiền tệ, làm tròn và hiển thị đúng ký hiệu.