Day6 Let's ODOO: Model(3) Decorators & Environment

依照昨天范例我们继续写下去

# -*- 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)

Method decorators

透过ODOO提供的装饰器来实现不同用途的方法,介绍常用的装饰器

@api.constrains

规定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(_("分数必须大於零"))

如范例所示,当其中一项分数小於零时便会报出错误提示,但要注意两点,

  1. 此装饰器无法控制relational field底下相关参数,例如我们限定teacher_id.mejor != math,老师科目不能等於数学,此装饰器并不会有任何效果。
  2. 装饰器只能限制view上的操作,如果是透过API方式新增进去,此装饰限制器也无效。

@api.depends

常用於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.onchange

@api.depends 相似,当指定的field会触发method

  @api.onchange('school_id')
  def _onchange_shcool(self):
      for record in self:
          record.school_city = record.school_id.city

当所选学校改变时,所在城市会跟着改变,有些要注意的地方:

  1. 只允许触发同一个model底下的field,@api.depends 则没有这个限制。
  2. 可以return一个dictionary,显示提示视窗,以ODOO Document为例。
return {
    'warning': {'title': "Warning", 'message': "What is this?", 'type': 'notification'},
}
  1. one2manymany2many field 无法透过此方法修改。

@api.model

self代表Model本身,与model recordset无关的方法,如: create method

    @api.model
    def create(self, values):
        return super(ResPartner, self).create(values)

Environment

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。


<<:  第6天~原来还有OKhttp这种语法

>>:  Day15 单纯贝氏分类器实作

day[11] Hello Line - 第一个Line讯息

本次铁人赛将通过Line机器人搭建专案,所以没有Line Developers的快去申请吧,会用到的...

Day 28 : Git

1. 为什麽要学 Git,可以做什麽呢? 学习到现在大家一定累积很多的程序码或是各式的档案,如何去做...

第十天:在 TeamCity 上完成第一个建置工作

在前一天的练习里,我们虽然只写了一个非常简单的 Hello World 程序,但只要能在 Run 面...

24.MYSQL NOT IN指令

有了IN就会有NOT IN,而写法跟用法一样的,就是不包含写的条件都会列出来 另外值得注意的是,IN...

全端入门Day24_後端程序撰写之多一点点的Node.js

昨天介绍了一些名词,今天继续提Node.js Node.js一点入门 今天直接贴上程序码,再去做解释...