Mở danh sách đơn hàng, đơn mới nhất luôn ở trên. Mở danh bạ, tên xếp A→Z. Không ai bấm nút "sắp xếp" — thứ tự đó là mặc định, khai bằng một thuộc tính duy nhất: _order. Khép lại chương "trường thông minh & thuộc tính model", bài này bàn cách đặt và những cái bẫy của nó.
_order = ORDER BY mặc định
_order là chuỗi khai trên model, được Odoo dịch thành mệnh đề ORDER BY của SQL cho mọi truy vấn không tự khai order:

Hình 1: _order = 'diem desc, name asc' — sắp theo nhiều tiêu chí, mỗi cái kèm asc/desc, ngăn bằng dấu phẩy. Đọc: "điểm giảm dần; cùng điểm thì tên tăng dần". Không khai _order thì mặc định là 'id' (theo id tăng dần). Muốn khác cho một truy vấn thì truyền order=... vào search.
Chạy thật — thứ tự đúng như khai
Tôi thêm _order = 'diem desc, name asc' vào model quan.the.thanh.vien, tạo 4 thẻ, rồi search([]) không truyền order. Output thật trên db blog19:

Hình 2: Output thật. search([]) trả về đúng thứ tự _order: ORD-A và ORD-D (điểm 100) lên đầu, cùng điểm thì tên A→Z nên A trước D; rồi ORD-B (50), cuối là ORD-C (10). Truyền order='name asc' thì bỏ qua _order, trả về A,B,C,D. _order chỉ là mặc định — luôn override được tại chỗ.
Vài ví dụ core
sale.order:'date_order desc, id desc'— đơn mới nhất lên đầu (cái bạn thấy hằng ngày).res.partner:'complete_name asc, id desc'— tên A→Z.- Không khai:
'id'— theo thứ tự tạo (id tăng dần).
id desc ở cuối thường là tiêu chí phá hòa: cùng ngày/tên thì bản ghi mới hơn (id lớn hơn) lên trước, đảm bảo thứ tự ổn định.
Ba cái bẫy hiệu năng
1. Sắp theo trường không index → chậm
Trên bảng lớn, ORDER BY một trường không có index buộc PostgreSQL sắp toàn bộ (sort tốn kém). Nếu _order theo trường hay dùng, cân nhắc thêm index=True cho trường đó.
2. Chỉ sắp được theo trường có cột SQL
_order phải theo trường có cột thật (thường store=True). Sắp theo computed không store sẽ lỗi — không có cột để ORDER BY. Đây là một lý do nữa để store=True khi cần sắp xếp.
3. Sắp theo Many2one = JOIN
_order = 'partner_id' không sắp theo id, mà theo trường định danh của partner (display_name/complete_name) — Odoo sinh JOIN. Đúng ý người dùng nhưng nặng hơn; nhiều tầng thì cân nhắc.
Override tại chỗ
_order chỉ là mặc định. Mọi lúc bạn có thể truyền order để đổi:
# Lấy 5 thẻ điểm cao nhất, bất kể _order
top = env['quan.the.thanh.vien'].search([], order='diem desc', limit=5)
Giao diện cũng cho người dùng bấm tiêu đề cột để đổi thứ tự — lúc đó Odoo truyền order tương ứng, _order bị bỏ qua cho lần xem đó.
Nhớ ba ý
_orderlàORDER BYmặc định của model ('diem desc, name asc'), áp cho mọi truy vấn không tự khaiorder; đo thật: điểm giảm dần, cùng điểm thì tên A→Z.- Thêm
id descở cuối làm tiêu chí phá hòa cho thứ tự ổn định; không khai_orderthì mặc định'id'. - Bẫy: sắp theo trường không index → chậm; theo computed không store → lỗi; theo Many2one → JOIN. Luôn override được bằng
order=...trongsearch.
Xong nhóm thuộc tính model. Chương tiếp đào sâu trường quan hệ — thao tác trên One2many/Many2many. Phần sau đi vào Command (0..6) — bộ lệnh đặc biệt để thêm/bớt/sửa bản ghi con trong trường quan hệ nhiều-nhiều và một-nhiều.