Odoo13中的方法装饰器

admin 2020-5-12 13513


Decorators allow you to modify the way a method behaves. It allows us to extend the behavior of another function or in short, it takes in a function and adds some functionality to the taken function and then returns the function. The decorators in odoo include:

api.depends

The function defined with this decorator will be called if any change happens in the fields specified in the depends for this function. The change to the field can be from ORM or changes in the form. If a compute function value depends on another field, then it must be specified using depends. Depends attribute can also be dotted field names like ‘product_id.categ_id’.

balance = fields.Monetary(string='Balance', store=True,  currency_field='company_currency_id',
   compute='_compute_balance',  help=" field holding the debit - credit")
@api.depends('debit', 'credit')
def _compute_balance(self):
   for line in self:
       line.balance = line.debit - line.credit


api.constraints

The function with this decorator will be called on create, write actions on the record. The function is invoked whenever the named fields of the record is modified. Validations can be done for the fields in this function. It can be done by raising an exception message when the validation fails. This can be done using raise ValidationError for example.

from odoo.exceptions import ValidationError
class AccountCashboxLine(models.Model):
   """ Cash Box Details """
   _name = 'account.cashbox.line'
@api.constrains('amount', 'amount_currency')
def _check_amount_currency(self):
   for line in self:
       if line.amount_currency != 0 and line.amount == 0:
           raise ValidationError(_('"Amount" must be specified.'))


api.onchange

The function with this decorator will be called when field value changes. Supports only single field names, dotted names like parent_id.field_name will not be considered. Onchange methods are invoked on pseudo-records that contain values of the form.

@api.onchange('partner_id')
def _onchange_partner_id(self):
   values = self._onchange_partner_id_values(self.partner_id.id if self.partner_id else False)
   self.update(values)

 

api.returns

Used to return some value when a particular method is called.

@api.returns('stock.warehouse', lambda value: value.id)
def get_warehouse(self):
   """ Returns warehouse id of warehouse that contains location """
   domain = [('view_location_id', 'parent_of', self.ids)]
   return self.env['stock.warehouse'].search(domain, limit=1)


api.model

This decorator helps in the migration of code. It will convert old API calls to new API signatures. Create and write functions coded in the old API can be easily updated using this API. This decorator can be used in methods where the self is a recordset and its model is relevant than its contents.

@api.model
def _get_default_invoice_date(self):
   return fields.Date.today() if self._context.get('default_type', 'entry') in ('in_invoice', 'in_refund', 'in_receipt') else False


api.model_create_multi

The function defined with this decorator takes a list of dictionaries and creates multiple records. The method can be called with a single or list of dictionaries.

@api.model_create_multi
def create(self, vals_list):
   records = super(SurveyUserInput, self).create(vals_list)
   records._check_for_failed_attempt()
   return records

Can be called with

record = model.create(vals)
records = model.create([vals, ...])


api.depends_context

This decorator takes context dependencies of the compute method, every argument in it will be a key in the context dictionary.

The keys with special support include:

force_company: this ensures that the computed field is recomputed based on current company or company in context.

uid: checks the current user and superuser flag

active_test: takes context value of env.context or field.context.

@api.depends('country_id')
@api.depends_context('force_company')
def _compute_product_pricelist(self):
   company = self.env.context.get('force_company', False)
   res = self.env['product.pricelist']._get_partner_pricelist_multi(self.ids, company_id=company)
   for p in self:
       p.property_product_pricelist = res.get(p.id)



最新回复 (0)
返回