Bạn thường xuyên cần "tên khách hàng của đơn cha" từ một dòng đơn hàng: line.order_id.partner_id.name. Gõ chuỗi dài đó khắp nơi — trong code, trong view, trong domain — vừa mỏi vừa dễ sai. Odoo có một loại trường giải quyết gọn: trường related. Nối tiếp computed và store, đây là "computed rút gọn" đặc biệt tiện.
related: khai đường đi, khỏi viết hàm
Trường related nhận tham số related='đường.đi.tới.trường' và tự lấy giá trị ở cuối chuỗi — không cần viết hàm compute:

Hình 1: related='order_id.partner_id' biến một chuỗi quan hệ thành trường phẳng order_partner_id — dùng thẳng như một trường bình thường. Bản chất: related chính là một computed rút gọn (Odoo tự sinh hàm _compute và @api.depends cho bạn). Thêm store=True thì lưu được để tìm/sắp.
Xem tận mắt trên core
sale.order.line có sẵn nhiều trường related thật. Đây là output thật trên db blog19:

Hình 2: Output thật. order_partner_id khai related='order_id.partner_id' — và giá trị của nó (line.order_partner_id.name = "Nguyễn Văn An") trùng khớp với line.order_id.partner_id.name. Vì store=True, ta còn tìm kiếm theo nó như một cột thật (search_count trả 7). salesman_id là related tới người bán của đơn, cho "OdooBot".
related vs computed thường
related là một computed, nhưng Odoo viết hộ bạn cả hàm lẫn @api.depends. So sánh:
# Cách dài (computed tự viết):
order_partner_id = fields.Many2one('res.partner', compute='_compute_partner', store=True)
@api.depends('order_id.partner_id')
def _compute_partner(self):
for line in self:
line.order_partner_id = line.order_id.partner_id
# Cách gọn (related) — TƯƠNG ĐƯƠNG, một dòng:
order_partner_id = fields.Many2one('res.partner', related='order_id.partner_id', store=True)
Khi việc chỉ là "lấy một trường của bản ghi liên kết", luôn dùng related — ngắn hơn, ít lỗi hơn.
Khi nào KHÔNG dùng related
- Logic phức tạp: có tính toán, nhiều nhánh
if, ghép chuỗi → dùng computed thường. - Cần biến đổi giá trị: related chỉ sao chép nguyên giá trị đích; muốn "+VAT", "viết hoa", "ghép 2 trường" thì phải computed.
store hay không cho related?
Giống bài store:
store=True: lưu cột, tìm kiếm/sắp xếp/báo cáo theo trường related được (nhưorder_partner_id). Đổi lại tốn ghi khi nguồn đổi.- Không store: chỉ đọc/hiển thị, lấy giá trị xuyên quan hệ mỗi lần. Ví dụ
tax_country_idở Hình 2 đểstore=Falsevì chỉ dùng nội bộ.
Quy tắc: related mà bạn muốn lọc/sắp trên giao diện thì store=True; chỉ hiển thị thì không store.
Một điểm tinh tế: related ghi ngược được
Khác computed thường, trường related có thể ghi ngược mặc định: gán line.order_partner_id = X sẽ ghi vào line.order_id.partner_id (trừ khi bạn khai readonly=True). Cẩn thận — điều này có thể vô tình sửa bản ghi cha. Thường nên để related readonly nếu chỉ dùng để hiển thị/lọc.
Nhớ ba ý
- Trường related (
related='a.b.c') rút gọn một chuỗi quan hệ thành trường phẳng, không cần viết hàm — bản chất là computed Odoo tự sinh. - Giá trị related = đúng giá trị ở cuối chuỗi (đo thật:
order_partner_id.name=order_id.partner_id.name= "Nguyễn Văn An");store=Trueđể tìm/sắp/báo cáo theo nó. - Dùng related khi chỉ lấy một trường của bản ghi liên kết; cần biến đổi/logic thì computed thường; nhớ related ghi ngược được — để
readonlynếu chỉ hiển thị.
Xong nhóm trường tính toán. Chương tiếp bảo vệ dữ liệu: ràng buộc. Phần sau đi vào @api.constrains — viết luật kiểm tra tính hợp lệ bằng Python, chặn dữ liệu sai ngay khi lưu.