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.

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:

Trường related trong Odoo 19 rút gọn chuỗi quan hệ thành một trường phẳng: vấn đề là gõ order_id.partner_id.name khắp nơi rất dài; giải pháp khai trường related bằng đường đi tới trường đích, order_partner_id bằng fields.Many2one res.partner với related bằng order_id.partner_id trỏ tới partner của đơn cha, store True muốn tìm sắp thì lưu, giờ chỉ cần line.order_partner_id thay vì line.order_id.partner_id; related thực chất là computed rút gọn, related a.b.c tương đương fields.X compute _compute_x store, api.depends a.b.c, def _compute_x self for r in self r.x bằng r.a.b.c Odoo tự sinh giúp bạn; nên dùng khi lấy một trường của bản ghi liên kết ra dùng thẳng trong form list domain, store True để tìm kiếm sắp xếp báo cáo, không nên khi logic phức tạp nhiều nhánh tính toán thì dùng computed thường

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:

Trường related chạy thật trên sale.order.line database blog19: vài trường related thật trong core, order_partner_id bằng order_id.partner_id store True, salesman_id bằng order_id.user_id store True, currency_id bằng order_id.currency_id store True, tax_country_id bằng order_id.tax_country_id store False; giá trị related bằng đúng giá trị ở cuối chuỗi quan hệ, line là dòng của đơn S00015, line.order_id.partner_id.name trả Nguyễn Văn An, line.order_partner_id.name cũng trả Nguyễn Văn An cùng giá trị, line.salesman_id.name trả OdooBot; related store True nên tìm kiếm theo nó được như cột thật, SOL.search_count order_partner_id bằng partner.id trả về 7

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 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.

  • 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.

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=False vì 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.

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 ý

  1. 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.
  2. 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ó.
  3. 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 — để readonly nế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.