视图模型与普通model模型差不多,主要区别在于:
1、 _auto 设置为 False:意思是不让odoo框架接管模型的处理,而是由我们自己来处理。
2、重写init函数:
3、定义的字段要与查询的结果类型一致。
4、查询中切记不要忘记id字段,不然会报错。
class report_employee(models.Model): _name = 'xxx.view.employee' _rec_name = 'employeeName' _description = u'员工视图' _auto = False employeeId = fields.Char(u'工号', readonly=True) employeeName = fields.Char(u'姓名', readonly=True) employeeCategory = fields.Char(u'人员身份', readonly=True) entryDate = fields.Date(u'入职日期', readonly=True) entryYear = fields.Integer(u'入职年份', readonly=True) entryMonth = fields.Char(u'入职月份', readonly=True) status = fields.Integer(u'状态', readonly=True) leaveDate = fields.Date(u'离职日期', readonly=True) leaveYear = fields.Integer(u'离职年份', readonly=True) leaveMonth = fields.Char(u'离职月份', readonly=True) entryPeriod = fields.Integer(u'入职周期', readonly=True) leaveDate = fields.Date(u'离职日期', readonly=True) lastExamPassDays = fields.Integer(u'距上次体检天数', readonly=True) def init(self): tools.sql.drop_view_if_exists(self.env.cr, self._table) self.env.cr.execute(''' CREATE OR REPLACE VIEW %s AS ( select a.*,coalesce(date_part('day',cast(now() as TIMESTAMP)-cast(b."examTime" as TIMESTAMP)),0) as "lastExamPassDays" from ( select id, "employeeId", "employeeName", case "isIntern" when true then '02' else '01' end as "employeeCategory", "entryDate", extract(year from "entryDate") as "entryYear", extract(month from "entryDate") as "entryMonth", 365-date_part('day',cast(now() as TIMESTAMP)-cast("entryDate" as TIMESTAMP)) as “entryPeriod”, case "isLeave" when true then 2 else 1 end as status, "leaveDate", extract(year from "leaveDate") as "leaveYear", extract(month from "leaveDate") as "leaveMonth" from xxx_employee ) a left join ( select x.* from xxx_exam x, ( select "employeeId",max(id) as id from xxx_exam group by "employeeId" ) y where x.id =y.id ) b on a.Id=b."employeeId" )''' % self._table)
BTW,视图模型比较适合复杂的查询或报表展示,避免嵌套过多的关联查询,使用方式且与普通模型一样。