odoo里API解读

Odoo自带的api装饰器主要有:model,multi,one,constrains,depends,onchange,returns 七个装饰器。

multi
multi则指self是多个记录的合集。因此,常使用for—in语句遍历self。 multi通常用于:在tree视图中点选多条记录,然后执行某方法,那么那个方法必须用@api.multi修饰,而参数中的self则代表选中的多条记录。 如果仅仅是在form视图下操作,那么self中通常只有当前正在操作的记录。
    @api.multi
    @api.depends('order_line.customer_lead', 'confirmation_date', 'order_line.state')
    def _compute_expected_date(self):
        """ For service and consumable, we only take the min dates. This method is extended in sale_stock to
            take the picking_policy of SO into account.
        """
        for order in self:
            dates_list = []
            confirm_date = fields.Datetime.from_string(order.confirmation_date if order.state == 'sale' else fields.Datetime.now())
            for line in order.order_line.filtered(lambda x: x.state != 'cancel' and not x._is_delivery()):
                dt = confirm_date + timedelta(days=line.customer_lead or 0.0)
                dates_list.append(dt)
            if dates_list:
                order.expected_date = fields.Datetime.to_string(min(dates_list))



@api.multi
def write(self, vals):
res = super(Employee, self).write(vals)
return res


@api.multi
def unlink(self):
resources = self.mapped('resource_id')
super(Employee, self).unlink()
return resources.unlink()


model:方法里不写默认是:model
此时的self仅代表模型本身,不含任何记录信息。
    @api.model
    def create(self, vals):
        if vals.get('name', _('New')) == _('New'):
            if 'company_id' in vals:
                vals['name'] = self.env['ir.sequence'].with_context(force_company=vals['company_id']).next_by_code('sale.order') or _('New')
            else:
                vals['name'] = self.env['ir.sequence'].next_by_code('sale.order') or _('New')

        # Makes sure partner_invoice_id', 'partner_shipping_id' and 'pricelist_id' are defined
        if any(f not in vals for f in ['partner_invoice_id', 'partner_shipping_id', 'pricelist_id']):
            partner = self.env['res.partner'].browse(vals.get('partner_id'))
            addr = partner.address_get(['delivery', 'invoice'])
            vals['partner_invoice_id'] = vals.setdefault('partner_invoice_id', addr['invoice'])
            vals['partner_shipping_id'] = vals.setdefault('partner_shipping_id', addr['delivery'])
            vals['pricelist_id'] = vals.setdefault('pricelist_id', partner.property_product_pricelist and partner.property_product_pricelist.id)
        result = super(SaleOrder, self).create(vals)
        return result




constrains
 字段的代码约束。
    @api.constrains('parent_id')
    def _check_parent_id(self):
        for employee in self:
            if not employee._check_recursion():
                raise ValidationError(_('You cannot create a recursive hierarchy.'))



    depends

 depends 主要用于compute方法,depends就是用来标该方法依赖于哪些字段的。
  
    @api.depends('parent_group', 'parent_group.users', 'groups', 'groups.users', 'explicit_users')
    def _compute_users(self):
        for record in self:
            users = record.mapped('groups.users')
            users |= record.mapped('explicit_users')
            users |= record.mapped('parent_group.users')
            record.update({'users': users, 'count_users': len(users)})


@api.depends('order_line.price_total')
def _amount_all(self):
"""
Compute the total amounts of the SO.
"""
for order in self:
amount_untaxed = amount_tax = 0.0
for line in order.order_line:
amount_untaxed += line.price_subtotal
amount_tax += line.price_tax
order.update({
'amount_untaxed': order.pricelist_id.currency_id.round(amount_untaxed),
'amount_tax': order.pricelist_id.currency_id.round(amount_tax),
'amount_total': amount_untaxed + amount_tax,
})



onchange
onchange的使用方法非常简单,就是当字段发生改变时,触发绑定的函数。
@api.onchange('team_type')
def _onchange_team_type(self):
if self.team_type == 'sales':
self.use_quotations = True
self.use_invoices = True
if not self.dashboard_graph_model:
self.dashboard_graph_model = 'sale.report'
else:
self.use_quotations = False
self.use_invoices = False
self.dashboard_graph_model = 'sale.report'
return super(CrmTeam, self)._onchange_team_type()


returns
returns的用法主要是用来指定返回值的格式,它接受三个参数,第一个为返回值的model,第二个为向下兼容的method,第三个为向上兼容的method
    @api.returns('self')
    def _default_employee_get(self):
        return self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)


@api.model
@api.returns('self', lambda value: value.id if value else False)
def _get_default_team_id(self, user_id=None):
if not user_id:
user_id = self.env.uid
company_id = self.sudo(user_id).env.user.company_id.id
team_id = self.env['crm.team'].sudo().search([
'|', ('user_id', '=', user_id), ('member_ids', '=', user_id),
'|', ('company_id', '=', False), ('company_id', 'child_of', [company_id])
], limit=1)
if not team_id and 'default_team_id' in self.env.context:
team_id = self.env['crm.team'].browse(self.env.context.get('default_team_id'))
if not team_id:
default_team_id = self.env.ref('sales_team.team_sales_department', raise_if_not_found=False)
if default_team_id:
try:
default_team_id.check_access_rule('read')
except AccessError:
return self.env['crm.team']
if self.env.context.get('default_type') != 'lead' or default_team_id.use_leads and default_team_id.active:
team_id = default_team_id
return team_id
 
one
one的用法主要用于self为单一记录的情况,意思是指:self仅代表当前正在操作的记录。
    @api.one
    def _compute_amount_undiscounted(self):
        total = 0.0
        for line in self.order_line:
            total += line.price_subtotal + line.price_unit * ((line.discount or 0.0) / 100.0) * line.product_uom_qty  # why is there a discount in a field named amount_undiscounted ??
        self.amount_undiscounted = total
 





 
原文地址:https://www.cnblogs.com/1314520xh/p/12180355.html