Ở bài 193 ta dựng khung module quan_ca_phe. Giờ viết phần lõi — một model. Model là cách Odoo mô tả một bảng dữ liệu bằng Python. Điều kỳ diệu: bạn chỉ khai class và các trường, còn tạo bảng trong cơ sở dữ liệu, thêm cột hệ thống, dựng màn hình nhập liệu thì Odoo lo hết. Bài này viết model thật, cài thật vào Odoo, và kiểm chứng nó chạy.
Viết model: một class Python
Trong models/the_thanh_vien.py, ta khai một "thẻ thành viên" cho khách của quán:

Hình 1: Model đầu tiên. class TheThanhVien(models.Model) — kế thừa lớp nền của Odoo. _name là tên kỹ thuật của model (quan.the.thanh.vien) — Odoo dùng nó để đặt tên bảng. _description là mô tả dễ đọc. Rồi ba trường: name (Char — chữ), partner_id (Many2one — liên kết tới một res.partner), diem (Integer — số). Mỗi trường có nhãn tiếng Việt để hiện trên giao diện.
Vài kiểu trường thường dùng: Char (chữ ngắn), Text (văn dài), Integer/Float (số), Boolean (đúng/sai), Date/Datetime (ngày), Many2one (trỏ tới một bản ghi khác), One2many/Many2many (quan hệ nhiều).
Cài vào Odoo — và bảng tự sinh trong PostgreSQL
Sau khi copy module vào thư mục addons và cài (-i quan_ca_phe), Odoo tự tạo bảng quan_the_thanh_vien trong PostgreSQL. Kiểm bằng câu lệnh trên chính cơ sở dữ liệu, các cột thật là:
id integer ← khoá chính, tự tăng
name character varying ← trường mình khai
partner_id integer ← trường mình khai (khoá ngoại)
diem integer ← trường mình khai
create_uid integer ← Odoo tự thêm: ai tạo
create_date timestamp without time zone ← Odoo tự thêm: tạo lúc nào
write_uid integer ← Odoo tự thêm: ai sửa gần nhất
write_date timestamp without time zone ← Odoo tự thêm: sửa lúc nào
Để ý: mình chỉ khai 3 trường (name, partner_id, diem), nhưng bảng có 8 cột. Odoo tự thêm id (khoá chính) và bốn cột kiểm toán (create_uid/create_date/write_uid/write_date) cho mọi model — nên bản ghi nào cũng biết ai tạo, khi nào, ai sửa cuối. Bạn không phải viết một dòng SQL nào.
Model thành màn hình nhập liệu thật
Đây là phần "thấy mới tin". Sau khi cài, mình tạo một bản ghi và mở nó trong Odoo:

Hình 2: Bản ghi VIP-0001 trên giao diện Odoo — Mã thẻ VIP-0001, Khách hàng Nguyễn Văn An, Điểm tích luỹ 120. Đây là dữ liệu thật lưu trong bảng vừa sinh. Từ vài dòng Python ở Hình 1, ta có một màn hình nhập liệu hoạt động đầy đủ — thêm/sửa/xoá/tìm kiếm — mà không viết thêm gì cho phần lưu trữ.
Ba trường Python → ba ô nhập trên form, đúng nhãn tiếng Việt đã khai. Đó là sức mạnh của Odoo: khai báo, không phải lập trình từng chi tiết.
Odoo làm giúp những gì?
Từ một class ngắn, Odoo tự lo:
- Tạo/cập nhật bảng trong PostgreSQL khớp các trường (kể cả khi bạn thêm trường sau này).
- Cột kiểm toán (
create_date,write_uid...) cho mọi bản ghi. - Các phương thức sẵn
create / write / search / unlink(thêm/sửa/tìm/xoá) — dùng ngay trong Python hoặc qua API. - Ràng buộc cơ bản:
required=Truelà bắt buộc nhập;Many2onetự thành khoá ngoại.
Bạn tập trung mô tả dữ liệu là gì; phần lưu trữ và thao tác Odoo lo.
Lưu ý cho người mới
_nameđặt theo dấu chấm (quan.the.thanh.vien) → Odoo đổi thành tên bảng gạch dưới (quan_the_thanh_vien).- Sửa model xong phải nâng cấp module (
-u quan_ca_phe) để Odoo cập nhật bảng — thêm trường mới mà quên nâng cấp thì cột chưa có. - Đừng xoá trường bừa khi đã có dữ liệu — mất dữ liệu cột đó.
- Cần khai quyền (file
security/ir.model.access.csvở bài 193) thì người dùng mới truy cập được model — thiếu là báo lỗi quyền.
Nhớ ba ý
- Model = một class Python kế thừa
models.Model, khai_namevà các trường (Char/Integer/Many2one...) — Odoo tự tạo bảng tương ứng trong PostgreSQL. - Odoo tự thêm
idvà các cột kiểm toán (create_date/write_uid...) cho mọi model, và sẵn các phương thứccreate/write/search. - Cài model xong là có ngay màn hình nhập liệu hoạt động — bạn khai báo dữ liệu, Odoo lo phần lưu trữ và thao tác.
Model đã có, dữ liệu đã lưu — nhưng giao diện tự sinh còn thô. Phần cuối ta định nghĩa view XML cho model: tự thiết kế form, danh sách và menu cho gọn đẹp — khép lại loạt Odoo 19.