Tạo báo cáo tùy chỉnh¶
SQL view là một kỹ thuật để tạo các báo cáo tùy chỉnh nhằm hiển thị dữ liệu mà không thể hiển thị bằng field và view của các model hiện có. Nói cách khác, kỹ thuật này giúp tránh việc tạo và tính toán không cần thiết các field bổ sung chỉ nhằm mục đích phân tích dữ liệu.
Tạo một model¶
Một SQL view được tạo theo cách tương tự như một model thông thường:
from odoo import fields, models
class ModuleReport(models.Model):
_name = 'module.report'
_description = "Module Report"
_rec_name = 'module_field'
_auto = False
Trong đó các thuộc tính:
_auto = Falsecho biết rằng chúng ta không muốn lưu trữ model này trong cơ sở dữ liệu_rec_namecho biết field nào của model đại diện cho tên của bản ghi (tức tên sẽ được dùng trong breadcrumb điều hướng khi mở form view của bản ghi)
và các field của nó được định nghĩa theo cùng cách như một model thông thường, ngoại trừ việc mỗi field đều được đánh dấu readonly=True.
Ghi chú
Đừng quên thêm model mới của bạn vào file bảo mật (security file).
Nạp dữ liệu cho model¶
Có 2 cách để nạp dữ liệu cho bảng của một SQL view:
ghi đè (override) phương thức
BaseModel.init(),thiết lập thuộc tính
_table_query.
Bất kể cách nào được sử dụng, một câu truy vấn SQL sẽ được thực thi để nạp dữ liệu cho model. Do đó, bất kỳ câu lệnh SQL nào cũng có thể được dùng để thu thập và/hoặc tính toán dữ liệu cần thiết, và bạn cần lưu ý rằng mình đang bỏ qua ORM (tức là nên đọc qua Security in Odoo nếu bạn chưa làm điều đó). Các cột được trả về từ câu lệnh SELECT sẽ nạp dữ liệu cho các field của model, vì vậy hãy đảm bảo tên cột của bạn khớp với tên field, hoặc sử dụng tên alias khớp với chúng.
Trong hầu hết các trường hợp, việc ghi đè phương thức BaseModel.init() là lựa chọn chuẩn mực và tốt hơn để sử dụng. Nó yêu cầu import tools và thường được viết như sau:
def init(self):
tools.drop_view_if_exists(self.env.cr, self._table)
self.env.cr.execute("""CREATE or REPLACE VIEW %s as (
SELECT
%s
FROM
%s
)""" % (self._table, self._select(), self._from()))
tools.drop_view_if_exists đảm bảo rằng một view xung đột sẽ không được tạo ra khi câu truy vấn SQL được thực thi. Đây là cách chuẩn để tách các phần khác nhau của câu truy vấn nhằm giúp việc mở rộng model dễ dàng hơn. Cách chính xác để chia câu truy vấn thành các phương thức không được chuẩn hóa, nhưng ít nhất các phương thức _select và _from là phổ biến, và tất nhiên, tất cả các phương thức này đều trả về chuỗi (string).
Thuộc tính _table_query được sử dụng khi view phụ thuộc vào context. Nó thường được viết như sau:
@property
def _table_query(self):
return 'SELECT %s FROM %s' % (self._select(), self._from())
và tuân theo cùng chuẩn về các phương thức _select và _from như BaseModel.init().
Một ví dụ về trường hợp nên sử dụng thuộc tính này thay vì ghi đè BaseModel.init() là trong môi trường đa công ty và đa tiền tệ, nơi các số tiền liên quan đến tiền tệ cần được quy đổi bằng tỷ giá hối đoái khi người dùng chuyển đổi giữa các công ty.
Sử dụng model¶
View và mục menu cho SQL view của bạn được tạo và sử dụng theo cùng cách như bất kỳ model Odoo nào khác. Vậy là bạn đã sẵn sàng để bắt đầu sử dụng SQL view của mình. Chúc bạn vui vẻ!
Mẹo bổ sung¶
Mẹo
Một sai lầm phổ biến trong SQL view là không xem xét đến việc trùng lặp dữ liệu do các phép JOIN bảng. Điều này có thể dẫn đến đếm sai khi sử dụng group_operator của field và/hoặc pivot view. Tốt nhất bạn nên kiểm thử SQL view của mình với đủ dữ liệu để đảm bảo giá trị field kết quả đúng như mong đợi.
Mẹo
Nếu bạn có một field mà bạn không muốn dùng làm measure (tức trong pivot view hoặc graph view), hãy thêm store=False vào field đó, và nó sẽ không hiển thị.