Ngoài số và chuỗi, Odoo có ba kiểu trường cho nội dung "nặng": Html (văn bản định dạng), Binary (tệp bất kỳ), Image (ảnh). Mỗi cái có xử lý riêng — đặc biệt Html tự chống XSS, và Image tự thu nhỏ ảnh. Nối tiếp Monetary, bài này khép lại chương "các kiểu trường".
Ba trường, ba mục đích

Hình 1: Html cho văn bản có định dạng (đậm, link, danh sách) — sanitize=True (mặc định) tự gỡ mã độc. Binary cho tệp bất kỳ, lưu dạng base64. Image là Binary chuyên cho ảnh: kiểm đúng là ảnh và tự resize theo max_width/max_height.
Html tự chống XSS — đo thật
Điểm quan trọng nhất của trường Html: nó tự làm sạch nội dung nguy hiểm trước khi lưu. Tôi thử nhét <script> và onclick vào — output thật trên db blog19:

Hình 2: Output thật. Chuỗi gốc có <script>alert(1)</script> và onclick="hack()". Sau khi lưu qua trường Html, đọc lại chỉ còn <p>Chào <b>bạn</b></p><a href="#">Link</a> — cả thẻ <script> lẫn thuộc tính onclick đã bị gỡ sạch. Đây là lớp phòng thủ XSS quan trọng: nội dung do người dùng nhập không thể chèn mã chạy được. Binary lưu/đọc base64 đúng nguyên; Image có max_width=512, max_height=512 để tự thu nhỏ.
Html: sanitize và các mức
sanitize=True là mặc định và nên giữ. Có các cờ tinh chỉnh:
sanitize_tags=True: chỉ giữ danh sách thẻ an toàn.sanitize_attributes=True: gỡ thuộc tính nguy hiểm (onclick,onerror...).sanitize_style=False: chặn cả thuộc tínhstyle(tránh XSS qua CSS).
Chỉ tắt sanitize khi nội dung đến từ nguồn hoàn toàn tin cậy (ví dụ template do admin viết). Nội dung do người dùng cuối nhập thì luôn sanitize.
Binary: cẩn thận file lớn
- Lưu dạng base64: đọc/ghi qua chuỗi base64, không phải bytes thô.
attachment=True(mặc định): file lưu vào filestore (đĩa/MinIO), không nhồi vào cột CSDL — quan trọng cho file lớn, tránh phình bảng.- Đừng lạm dụng: file rất lớn (video) nên dùng hệ lưu trữ riêng, không nhét vào Binary.
Image: hơn Binary một bậc
Image = Binary + hai thứ:
- Kiểm đúng là ảnh: gán dữ liệu không phải ảnh sẽ lỗi.
- Tự resize:
max_width/max_heightthu nhỏ ảnh quá lớn — tiết kiệm dung lượng, tăng tốc tải.
Odoo core còn dùng mẫu nhiều kích cỡ: khai image_1920 (gốc) rồi các trường related image_512, image_256, image_128 tự sinh — giao diện chọn cỡ phù hợp (thumbnail nhỏ, xem lớn ảnh gốc). Đây là lý do avatar/logo tải nhanh ở mọi nơi.
Hiển thị trên view
- Html: widget mặc định là trình soạn thảo giàu định dạng (giống EasyMDE nhưng của Odoo).
- Binary: nút tải lên/tải xuống, hiện tên tệp.
- Image: khung ảnh, click để đổi; dùng
widget="image".
Nhớ ba ý
- Html cho văn bản định dạng và tự làm sạch XSS (
sanitize=Truemặc định) — đo thật:<script>vàonclickbị gỡ sạch; chỉ tắt sanitize với nguồn tin cậy. - Binary cho tệp bất kỳ, lưu base64 vào filestore (
attachment=True) — hợp file vừa; file rất lớn dùng lưu trữ riêng. - Image = Binary + kiểm đúng ảnh + tự resize (
max_width/max_height); Odoo dùng mẫu nhiều kích cỡ (image_1920/image_512...) cho avatar/logo.
Xong toàn bộ các kiểu trường. Có một nhóm trường tưởng đơn giản nhưng đầy bẫy: ngày giờ. Phần sau đi vào Date/Datetime và múi giờ — vì sao Odoo lưu UTC, hiển thị theo giờ người dùng, và những lỗi lệch giờ hay gặp.