依照昨天範例我們繼續寫下去
# -*- coding: utf-8 -*-
from odoo import api, models, fields
from odoo.exceptions import ValidationError
class ResStudent(models.Model):
    _name = 'res.student'
    _inherit = 'res.partner'
    _description = 'Student'
    nickname = fields.Char(string='綽號')
    math_score = fields.Float(string='數學成績')
    chinese_score = fields.Float(string='國文成績')
    avg_score = fields.Float(string='學期平均', compute='_compute_score')
    birthday = fields.Date(string='生日', required=True)
    school_id = fields.Many2one('res.company', string='所屬學校')
    school_city = fields.Char(string='所在城市', related='school_id.city')
    senior_id = fields.Many2one('res.student', string='直屬學長姐')
    junior_ids = fields.One2many('res.student', 'senior_id', string='直屬學弟妹')
    teacher_ids = fields.Many2many('res.partner', string='指導老師', domain=[('is_company', '!=', True)])
    gender = fields.Selection([("male", "男"), ("female", "女"), ("other", "其他")], string='性別')
    is_leadership = fields.Boolean(default=False)
    is_active = fields.Boolean(default=True)
    channel_ids = fields.Many2many('mail.channel', 'mail_channel_profile_partner', 'partner_id', 'channel_id', copy=False)
    @api.depends('math_score', 'chinese_score')
    def _compute_score(self):
        for record in self:
            record.avg_score = (record.math_score + record.chinese_score) / 2
    @api.onchange('school_id')
    def _onchange_shcool(self):
        for record in self:
            record.school_city = record.school_id.city
    @api.constrains('math_score', 'chinese_score')
    def _validate_score(self):
        for record in self:
            if record.math_score < 0 or record.chinese_score < 0:
                raise ValidationError(_("分數必須大於零"))
    @api.model
    def create(self, values):
        if values.get('is_active') is False:
            values.update({
                'is_leadership': False
            })
        return super(ResStudent, self).create(values)
透過ODOO提供的裝飾器來實現不同用途的方法,介紹常用的裝飾器
規定fields要符合設定條件,否則無法新增或修改。
  @api.constrains('math_score', 'chinese_score')
  def _validate_score(self):
      for record in self:
          if record.math_score < 0 or record.chinese_score < 0:
              raise ValidationError(_("分數必須大於零"))
如範例所示,當其中一項分數小於零時便會報出錯誤提示,但要注意兩點,
teacher_id.mejor != math,老師科目不能等於數學,此裝飾器並不會有任何效果。常用於compute fields,當指定的field更改時會觸發method。
  @api.depends('math_score', 'chinese_score')
  def _compute_total(self):
      for record in self:
          record.avg_score = (record.math_score + record.chinese_score) / 2
當成績改變時,平均成績也會重新計算,同樣只作用於odoo view表層,直接更改的時候不會觸發。
與@api.depends 相似,當指定的field會觸發method
  @api.onchange('school_id')
  def _onchange_shcool(self):
      for record in self:
          record.school_city = record.school_id.city
當所選學校改變時,所在城市會跟著改變,有些要注意的地方:
@api.depends 則沒有這個限制。return {
    'warning': {'title': "Warning", 'message': "What is this?", 'type': 'notification'},
}
one2many 和 many2many field 無法透過此方法修改。self代表Model本身,與model recordset無關的方法,如: create method
    @api.model
    def create(self, values):
        return super(ResPartner, self).create(values)
env裡存了許多快取可供使用者查詢及修改,日後也會透過此方法對DB做操作。
user: 目前使用的帳戶
self.env.user
model: 獲取指定model
self.env['res.partner'] #res_partner為model name
lang: 獲取當前語
self.env.lang
company: 獲取當前company branch
self.env.company
companies:獲取此user access的所有company branch
self.env.companies
Decorators與Environment就介紹到這邊,明天我們來介紹model內的ORM method。