天天看點

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