[IMP] api: remove deprecated decorators
This commit is contained in:
@@ -17,7 +17,6 @@ class AccountAnalyticLine(models.Model):
|
|||||||
code = fields.Char(size=8)
|
code = fields.Char(size=8)
|
||||||
ref = fields.Char(string='Ref.')
|
ref = fields.Char(string='Ref.')
|
||||||
|
|
||||||
@api.v8
|
|
||||||
@api.onchange('product_id', 'product_uom_id', 'unit_amount', 'currency_id')
|
@api.onchange('product_id', 'product_uom_id', 'unit_amount', 'currency_id')
|
||||||
def on_change_unit_amount(self):
|
def on_change_unit_amount(self):
|
||||||
if not self.product_id:
|
if not self.product_id:
|
||||||
|
|||||||
@@ -2779,7 +2779,6 @@ class AccountMoveLine(models.Model):
|
|||||||
# LOW-LEVEL METHODS
|
# LOW-LEVEL METHODS
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
""" change index on partner_id to a multi-column index on (partner_id, ref), the new index will behave in the
|
""" change index on partner_id to a multi-column index on (partner_id, ref), the new index will behave in the
|
||||||
same way when we search on partner_id, with the addition of being optimal when having a query that will
|
same way when we search on partner_id, with the addition of being optimal when having a query that will
|
||||||
|
|||||||
@@ -164,7 +164,6 @@ class AccountInvoiceReport(models.Model):
|
|||||||
COALESCE(partner.country_id, commercial_partner.country_id)
|
COALESCE(partner.country_id, commercial_partner.country_id)
|
||||||
'''
|
'''
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
tools.drop_view_if_exists(self.env.cr, self._table)
|
tools.drop_view_if_exists(self.env.cr, self._table)
|
||||||
self.env.cr.execute('''
|
self.env.cr.execute('''
|
||||||
|
|||||||
@@ -231,7 +231,6 @@ class BaseAutomation(models.Model):
|
|||||||
)
|
)
|
||||||
return any(differ(field.name) for field in self.trigger_field_ids)
|
return any(differ(field.name) for field in self.trigger_field_ids)
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def _register_hook(self):
|
def _register_hook(self):
|
||||||
""" Patch models that should trigger action rules based on creation,
|
""" Patch models that should trigger action rules based on creation,
|
||||||
modification, deletion of records and form onchanges.
|
modification, deletion of records and form onchanges.
|
||||||
|
|||||||
@@ -45,13 +45,11 @@ class BaseGengoTranslations(models.TransientModel):
|
|||||||
sync_limit = fields.Integer("No. of terms to sync", default=20)
|
sync_limit = fields.Integer("No. of terms to sync", default=20)
|
||||||
authorized_credentials = fields.Boolean('The private and public keys are valid')
|
authorized_credentials = fields.Boolean('The private and public keys are valid')
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
icp = self.env['ir.config_parameter'].sudo()
|
icp = self.env['ir.config_parameter'].sudo()
|
||||||
if not icp.get_param(self.GENGO_KEY):
|
if not icp.get_param(self.GENGO_KEY):
|
||||||
icp.set_param(self.GENGO_KEY, str(uuid.uuid4()))
|
icp.set_param(self.GENGO_KEY, str(uuid.uuid4()))
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def get_gengo_key(self):
|
def get_gengo_key(self):
|
||||||
icp = self.env['ir.config_parameter'].sudo()
|
icp = self.env['ir.config_parameter'].sudo()
|
||||||
return icp.get_param(self.GENGO_KEY, default="Undefined")
|
return icp.get_param(self.GENGO_KEY, default="Undefined")
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ class Lead(models.Model):
|
|||||||
'utm.mixin', 'format.address.mixin', 'phone.validation.mixin']
|
'utm.mixin', 'format.address.mixin', 'phone.validation.mixin']
|
||||||
_primary_email = 'email_from'
|
_primary_email = 'email_from'
|
||||||
|
|
||||||
@api.model_cr_context
|
|
||||||
def _auto_init(self):
|
def _auto_init(self):
|
||||||
res = super(Lead, self)._auto_init()
|
res = super(Lead, self)._auto_init()
|
||||||
tools.create_index(self._cr, 'crm_lead_create_date_team_id_idx',
|
tools.create_index(self._cr, 'crm_lead_create_date_team_id_idx',
|
||||||
@@ -146,7 +145,6 @@ class Lead(models.Model):
|
|||||||
('check_probability', 'check(probability >= 0 and probability <= 100)', 'The probability of closing the deal should be between 0% and 100%!')
|
('check_probability', 'check(probability >= 0 and probability <= 100)', 'The probability of closing the deal should be between 0% and 100%!')
|
||||||
]
|
]
|
||||||
|
|
||||||
@api.model_cr_context
|
|
||||||
def _auto_init(self):
|
def _auto_init(self):
|
||||||
res = super(Lead, self)._auto_init()
|
res = super(Lead, self)._auto_init()
|
||||||
tools.create_index(self._cr, 'crm_lead_user_id_team_id_type_index',
|
tools.create_index(self._cr, 'crm_lead_user_id_team_id_type_index',
|
||||||
|
|||||||
@@ -75,7 +75,6 @@ class ActivityReport(models.Model):
|
|||||||
m.model = 'crm.lead' AND (m.mail_activity_type_id IS NOT NULL OR m.subtype_id = %s)
|
m.model = 'crm.lead' AND (m.mail_activity_type_id IS NOT NULL OR m.subtype_id = %s)
|
||||||
""" % (disccusion_subtype.id,)
|
""" % (disccusion_subtype.id,)
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
tools.drop_view_if_exists(self._cr, self._table)
|
tools.drop_view_if_exists(self._cr, self._table)
|
||||||
self._cr.execute("""
|
self._cr.execute("""
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ class CRMRevealView(models.Model):
|
|||||||
reveal_state = fields.Selection([('to_process', 'To Process'), ('not_found', 'Not Found')], default='to_process', string="State", index=True)
|
reveal_state = fields.Selection([('to_process', 'To Process'), ('not_found', 'Not Found')], default='to_process', string="State", index=True)
|
||||||
create_date = fields.Datetime(index=True)
|
create_date = fields.Datetime(index=True)
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
self._cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('crm_reveal_view_ip_rule_id',))
|
self._cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('crm_reveal_view_ip_rule_id',))
|
||||||
if not self._cr.fetchone():
|
if not self._cr.fetchone():
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ class HrEmployeePublic(models.Model):
|
|||||||
def _get_fields(self):
|
def _get_fields(self):
|
||||||
return ','.join('emp.%s' % name for name, field in self._fields.items() if field.store and field.type not in ['many2many', 'one2many'])
|
return ','.join('emp.%s' % name for name, field in self._fields.items() if field.store and field.type not in ['many2many', 'one2many'])
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
tools.drop_view_if_exists(self.env.cr, self._table)
|
tools.drop_view_if_exists(self.env.cr, self._table)
|
||||||
self.env.cr.execute("""CREATE or REPLACE VIEW %s as (
|
self.env.cr.execute("""CREATE or REPLACE VIEW %s as (
|
||||||
|
|||||||
@@ -252,7 +252,6 @@ class HolidaysRequest(models.Model):
|
|||||||
('duration_check', "CHECK ( number_of_days >= 0 )", "If you want to change the number of days you should use the 'period' mode"),
|
('duration_check', "CHECK ( number_of_days >= 0 )", "If you want to change the number of days you should use the 'period' mode"),
|
||||||
]
|
]
|
||||||
|
|
||||||
@api.model_cr_context
|
|
||||||
def _auto_init(self):
|
def _auto_init(self):
|
||||||
res = super(HolidaysRequest, self)._auto_init()
|
res = super(HolidaysRequest, self)._auto_init()
|
||||||
tools.create_index(self._cr, 'hr_leave_date_to_date_from_index',
|
tools.create_index(self._cr, 'hr_leave_date_to_date_from_index',
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ class TimesheetAttendance(models.Model):
|
|||||||
total_attendance = fields.Float()
|
total_attendance = fields.Float()
|
||||||
total_difference = fields.Float()
|
total_difference = fields.Float()
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
self._cr.execute("""CREATE OR REPLACE VIEW %s AS (
|
self._cr.execute("""CREATE OR REPLACE VIEW %s AS (
|
||||||
SELECT
|
SELECT
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ class ImLivechatReportChannel(models.Model):
|
|||||||
is_unrated = fields.Integer('Session not rated', readonly=True)
|
is_unrated = fields.Integer('Session not rated', readonly=True)
|
||||||
partner_id = fields.Many2one('res.partner', 'Operator', readonly=True)
|
partner_id = fields.Many2one('res.partner', 'Operator', readonly=True)
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
# Note : start_date_hour must be remove when the read_group will allow grouping on the hour of a datetime. Don't forget to change the view !
|
# Note : start_date_hour must be remove when the read_group will allow grouping on the hour of a datetime. Don't forget to change the view !
|
||||||
tools.drop_view_if_exists(self.env.cr, 'im_livechat_report_channel')
|
tools.drop_view_if_exists(self.env.cr, 'im_livechat_report_channel')
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ class ImLivechatReportOperator(models.Model):
|
|||||||
time_to_answer = fields.Float('Time to answer', digits=(16, 2), readonly=True, group_operator="avg", help="Average time to give the first answer to the visitor")
|
time_to_answer = fields.Float('Time to answer', digits=(16, 2), readonly=True, group_operator="avg", help="Average time to give the first answer to the visitor")
|
||||||
duration = fields.Float('Average duration', digits=(16, 2), readonly=True, group_operator="avg", help="Duration of the conversation (in seconds)")
|
duration = fields.Float('Average duration', digits=(16, 2), readonly=True, group_operator="avg", help="Duration of the conversation (in seconds)")
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
# Note : start_date_hour must be remove when the read_group will allow grouping on the hour of a datetime. Don't forget to change the view !
|
# Note : start_date_hour must be remove when the read_group will allow grouping on the hour of a datetime. Don't forget to change the view !
|
||||||
tools.drop_view_if_exists(self.env.cr, 'im_livechat_report_operator')
|
tools.drop_view_if_exists(self.env.cr, 'im_livechat_report_operator')
|
||||||
|
|||||||
@@ -302,7 +302,6 @@ class L10nInAccountInvoiceReport(models.Model):
|
|||||||
"""
|
"""
|
||||||
return group_by_str
|
return group_by_str
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
tools.drop_view_if_exists(self.env.cr, self._table)
|
tools.drop_view_if_exists(self.env.cr, self._table)
|
||||||
self.env.cr.execute("""CREATE or REPLACE VIEW %s AS (
|
self.env.cr.execute("""CREATE or REPLACE VIEW %s AS (
|
||||||
|
|||||||
@@ -101,7 +101,6 @@ class L10nInPaymentReport(models.AbstractModel):
|
|||||||
AND tax.tax_group_id in (SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name in ('igst_group','gst_group'))
|
AND tax.tax_group_id in (SELECT res_id FROM ir_model_data WHERE module='l10n_in' AND name in ('igst_group','gst_group'))
|
||||||
AND ac.internal_type IN ('receivable', 'payable') AND am.state = 'posted'"""
|
AND ac.internal_type IN ('receivable', 'payable') AND am.state = 'posted'"""
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
tools.drop_view_if_exists(self.env.cr, self._table)
|
tools.drop_view_if_exists(self.env.cr, self._table)
|
||||||
self.env.cr.execute("""CREATE or REPLACE VIEW %s AS (
|
self.env.cr.execute("""CREATE or REPLACE VIEW %s AS (
|
||||||
|
|||||||
@@ -89,7 +89,6 @@ class L10nInExemptedReport(models.Model):
|
|||||||
"""
|
"""
|
||||||
return from_str
|
return from_str
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
tools.drop_view_if_exists(self.env.cr, self._table)
|
tools.drop_view_if_exists(self.env.cr, self._table)
|
||||||
self._cr.execute("""CREATE OR REPLACE VIEW %s AS (%s %s)""" % (
|
self._cr.execute("""CREATE OR REPLACE VIEW %s AS (%s %s)""" % (
|
||||||
|
|||||||
@@ -98,7 +98,6 @@ class L10nInProductHsnReport(models.Model):
|
|||||||
"""
|
"""
|
||||||
return from_str
|
return from_str
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
tools.drop_view_if_exists(self.env.cr, self._table)
|
tools.drop_view_if_exists(self.env.cr, self._table)
|
||||||
self.env.cr.execute("""CREATE OR REPLACE VIEW %s AS (%s %s)""" % (
|
self.env.cr.execute("""CREATE OR REPLACE VIEW %s AS (%s %s)""" % (
|
||||||
|
|||||||
@@ -220,7 +220,6 @@ class AliasMixin(models.AbstractModel):
|
|||||||
aliases.unlink()
|
aliases.unlink()
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@api.model_cr_context
|
|
||||||
def _init_column(self, name):
|
def _init_column(self, name):
|
||||||
""" Create aliases for existing rows. """
|
""" Create aliases for existing rows. """
|
||||||
super(AliasMixin, self)._init_column(name)
|
super(AliasMixin, self)._init_column(name)
|
||||||
|
|||||||
@@ -410,7 +410,6 @@ class Channel(models.Model):
|
|||||||
return True
|
return True
|
||||||
return super(Channel, self)._alias_check_contact(message, message_dict, alias)
|
return super(Channel, self)._alias_check_contact(message, message_dict, alias)
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
self._cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('mail_channel_partner_seen_message_id_idx',))
|
self._cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('mail_channel_partner_seen_message_id_idx',))
|
||||||
if not self._cr.fetchone():
|
if not self._cr.fetchone():
|
||||||
|
|||||||
@@ -585,7 +585,6 @@ class Message(models.Model):
|
|||||||
# mail_message internals
|
# mail_message internals
|
||||||
#------------------------------------------------------
|
#------------------------------------------------------
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
self._cr.execute("""SELECT indexname FROM pg_indexes WHERE indexname = 'mail_message_model_res_id_idx'""")
|
self._cr.execute("""SELECT indexname FROM pg_indexes WHERE indexname = 'mail_message_model_res_id_idx'""")
|
||||||
if not self._cr.fetchone():
|
if not self._cr.fetchone():
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ class Notification(models.Model):
|
|||||||
], string='Failure type')
|
], string='Failure type')
|
||||||
failure_reason = fields.Text('Failure reason', copy=False)
|
failure_reason = fields.Text('Failure reason', copy=False)
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
self._cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('mail_notification_res_partner_id_is_read_email_status_mail_message_id',))
|
self._cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('mail_notification_res_partner_id_is_read_email_status_mail_message_id',))
|
||||||
if not self._cr.fetchone():
|
if not self._cr.fetchone():
|
||||||
|
|||||||
@@ -430,9 +430,6 @@ class MailComposer(models.TransientModel):
|
|||||||
values['body'] = values.pop('body_html')
|
values['body'] = values.pop('body_html')
|
||||||
|
|
||||||
# This onchange should return command instead of ids for x2many field.
|
# This onchange should return command instead of ids for x2many field.
|
||||||
# ORM handle the assignation of command list on new onchange (api.v8),
|
|
||||||
# this force the complete replacement of x2many field with
|
|
||||||
# command and is compatible with onchange api.v7
|
|
||||||
values = self._convert_to_write(values)
|
values = self._convert_to_write(values)
|
||||||
|
|
||||||
return {'value': values}
|
return {'value': values}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ class MassMailingReport(models.Model):
|
|||||||
string='Status', readonly=True)
|
string='Status', readonly=True)
|
||||||
email_from = fields.Char('From', readonly=True)
|
email_from = fields.Char('From', readonly=True)
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
"""Mass Mail Statistical Report: based on mail.mail.statistics that models the various
|
"""Mass Mail Statistical Report: based on mail.mail.statistics that models the various
|
||||||
statistics collected for each mailing, and mail.mass_mailing model that models the
|
statistics collected for each mailing, and mail.mass_mailing model that models the
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ class ReportMembership(models.Model):
|
|||||||
company_id = fields.Many2one('res.company', string='Company', readonly=True)
|
company_id = fields.Many2one('res.company', string='Company', readonly=True)
|
||||||
quantity = fields.Integer(readonly=True)
|
quantity = fields.Integer(readonly=True)
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
'''Create the view'''
|
'''Create the view'''
|
||||||
tools.drop_view_if_exists(self._cr, self._table)
|
tools.drop_view_if_exists(self._cr, self._table)
|
||||||
|
|||||||
@@ -94,7 +94,6 @@ class PosOrderReport(models.Model):
|
|||||||
SUM(l.qty * u.factor) != 0
|
SUM(l.qty * u.factor) != 0
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
tools.drop_view_if_exists(self._cr, self._table)
|
tools.drop_view_if_exists(self._cr, self._table)
|
||||||
self._cr.execute("""
|
self._cr.execute("""
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ class PurchaseBillUnion(models.Model):
|
|||||||
vendor_bill_id = fields.Many2one('account.move', string='Vendor Bill', readonly=True)
|
vendor_bill_id = fields.Many2one('account.move', string='Vendor Bill', readonly=True)
|
||||||
purchase_order_id = fields.Many2one('purchase.order', string='Purchase Order', readonly=True)
|
purchase_order_id = fields.Many2one('purchase.order', string='Purchase Order', readonly=True)
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
tools.drop_view_if_exists(self.env.cr, 'purchase_bill_union')
|
tools.drop_view_if_exists(self.env.cr, 'purchase_bill_union')
|
||||||
self.env.cr.execute("""
|
self.env.cr.execute("""
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ class PurchaseReport(models.Model):
|
|||||||
qty_billed = fields.Float('Qty Billed', readonly=True)
|
qty_billed = fields.Float('Qty Billed', readonly=True)
|
||||||
qty_to_be_billed = fields.Float('Qty to be Billed', readonly=True)
|
qty_to_be_billed = fields.Float('Qty to be Billed', readonly=True)
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
# self._table = sale_report
|
# self._table = sale_report
|
||||||
tools.drop_view_if_exists(self.env.cr, self._table)
|
tools.drop_view_if_exists(self.env.cr, self._table)
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ class PosSaleReport(models.Model):
|
|||||||
AS foo""" % (self._table, self._from())
|
AS foo""" % (self._table, self._from())
|
||||||
return request
|
return request
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
tools.drop_view_if_exists(self.env.cr, self._table)
|
tools.drop_view_if_exists(self.env.cr, self._table)
|
||||||
self.env.cr.execute(self.get_main_request())
|
self.env.cr.execute(self.get_main_request())
|
||||||
|
|||||||
@@ -144,7 +144,6 @@ class SaleReport(models.Model):
|
|||||||
|
|
||||||
return '%s (SELECT %s FROM %s WHERE l.product_id IS NOT NULL GROUP BY %s)' % (with_, select_, from_, groupby_)
|
return '%s (SELECT %s FROM %s WHERE l.product_id IS NOT NULL GROUP BY %s)' % (with_, select_, from_, groupby_)
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
# self._table = sale_report
|
# self._table = sale_report
|
||||||
tools.drop_view_if_exists(self.env.cr, self._table)
|
tools.drop_view_if_exists(self.env.cr, self._table)
|
||||||
|
|||||||
@@ -354,7 +354,6 @@ class StockMove(models.Model):
|
|||||||
user_warning += _('\n\nBlocking: %s') % ' ,'.join(moves_error.mapped('name'))
|
user_warning += _('\n\nBlocking: %s') % ' ,'.join(moves_error.mapped('name'))
|
||||||
raise UserError(user_warning)
|
raise UserError(user_warning)
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
self._cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('stock_move_product_location_index',))
|
self._cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('stock_move_product_location_index',))
|
||||||
if not self._cr.fetchone():
|
if not self._cr.fetchone():
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ class ReportStockForecat(models.Model):
|
|||||||
picking_id = fields.Many2one('stock.picking', string='Picking', readonly=True)
|
picking_id = fields.Many2one('stock.picking', string='Picking', readonly=True)
|
||||||
reference = fields.Char('Reference')
|
reference = fields.Char('Reference')
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
tools.drop_view_if_exists(self._cr, 'report_stock_forecast')
|
tools.drop_view_if_exists(self._cr, 'report_stock_forecast')
|
||||||
query = """
|
query = """
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ class ResUsers(models.Model):
|
|||||||
current_website = self.env['website'].get_current_website()
|
current_website = self.env['website'].get_current_website()
|
||||||
return current_website.auth_signup_uninvited or super(ResUsers, self)._get_signup_invitation_scope()
|
return current_website.auth_signup_uninvited or super(ResUsers, self)._get_signup_invitation_scope()
|
||||||
|
|
||||||
@api.model_cr_context
|
|
||||||
def _auto_init(self):
|
def _auto_init(self):
|
||||||
result = super(ResUsers, self)._auto_init()
|
result = super(ResUsers, self)._auto_init()
|
||||||
# Use unique index to implement unique constraint per website, even if website_id is null
|
# Use unique index to implement unique constraint per website, even if website_id is null
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ class CrmPartnerReportAssign(models.Model):
|
|||||||
'grade_id', 'parent_id', 'team_id', 'user_id'],
|
'grade_id', 'parent_id', 'team_id', 'user_id'],
|
||||||
}
|
}
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
"""
|
"""
|
||||||
CRM Lead Report
|
CRM Lead Report
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ class ReportEventRegistrationQuestions(models.Model):
|
|||||||
answer_id = fields.Many2one(comodel_name='event.answer', string='Answer')
|
answer_id = fields.Many2one(comodel_name='event.answer', string='Answer')
|
||||||
event_id = fields.Many2one(comodel_name='event.event', string='Event')
|
event_id = fields.Many2one(comodel_name='event.event', string='Event')
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
""" Event Question main report """
|
""" Event Question main report """
|
||||||
tools.drop_view_if_exists(self._cr, 'event_question_report')
|
tools.drop_view_if_exists(self._cr, 'event_question_report')
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ class website_form_model_fields(models.Model):
|
|||||||
_description = 'Fields'
|
_description = 'Fields'
|
||||||
_inherit = 'ir.model.fields'
|
_inherit = 'ir.model.fields'
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
# set all existing unset website_form_blacklisted fields to ``true``
|
# set all existing unset website_form_blacklisted fields to ``true``
|
||||||
# (so that we can use it as a whitelist rather than a blacklist)
|
# (so that we can use it as a whitelist rather than a blacklist)
|
||||||
|
|||||||
@@ -294,7 +294,6 @@ class Channel(models.Model):
|
|||||||
# ORM Overrides
|
# ORM Overrides
|
||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
|
|
||||||
@api.model_cr_context
|
|
||||||
def _init_column(self, column_name):
|
def _init_column(self, column_name):
|
||||||
""" Initialize the value of the given column for existing rows.
|
""" Initialize the value of the given column for existing rows.
|
||||||
Overridden here because we need to generate different access tokens
|
Overridden here because we need to generate different access tokens
|
||||||
|
|||||||
@@ -1205,20 +1205,6 @@ Porting from the old API to the new API
|
|||||||
:attr:`~odoo.models.Model.write_date` fields: they are now created as
|
:attr:`~odoo.models.Model.write_date` fields: they are now created as
|
||||||
regular "legitimate" fields, and can be read and written like any other
|
regular "legitimate" fields, and can be read and written like any other
|
||||||
field out-of-the-box
|
field out-of-the-box
|
||||||
* when straight conversion is impossible (semantics can not be bridged) or the
|
|
||||||
"old API" version is not desirable and could be improved for the new API, it
|
|
||||||
is possible to use completely different "old API" and "new API"
|
|
||||||
implementations for the same method name using :func:`~odoo.api.v7` and
|
|
||||||
:func:`~odoo.api.v8`. The method should first be defined using the
|
|
||||||
old-API style and decorated with :func:`~odoo.api.v7`, it should then be
|
|
||||||
re-defined using the exact same name but the new-API style and decorated
|
|
||||||
with :func:`~odoo.api.v8`. Calls from an old-API context will be
|
|
||||||
dispatched to the first implementation and calls from a new-API context will
|
|
||||||
be dispatched to the second implementation. One implementation can call (and
|
|
||||||
frequently does) call the other by switching context.
|
|
||||||
|
|
||||||
.. danger:: using these decorators makes methods extremely difficult to
|
|
||||||
override and harder to understand and document
|
|
||||||
* uses of :attr:`~odoo.models.Model._columns` or
|
* uses of :attr:`~odoo.models.Model._columns` or
|
||||||
:attr:`~odoo.models.Model._all_columns` should be replaced by
|
:attr:`~odoo.models.Model._all_columns` should be replaced by
|
||||||
:attr:`~odoo.models.Model._fields`, which provides access to instances of
|
:attr:`~odoo.models.Model._fields`, which provides access to instances of
|
||||||
@@ -1277,28 +1263,3 @@ decorating the old-style method:
|
|||||||
* disabling it entirely, by decorating a method with
|
* disabling it entirely, by decorating a method with
|
||||||
:func:`~odoo.api.noguess` there will be no bridging and methods will be
|
:func:`~odoo.api.noguess` there will be no bridging and methods will be
|
||||||
called the exact same way from the new and old API styles
|
called the exact same way from the new and old API styles
|
||||||
* defining the bridge explicitly, this is mostly for methods which are matched
|
|
||||||
incorrectly (because parameters are named in unexpected ways):
|
|
||||||
|
|
||||||
:func:`~odoo.api.cr`
|
|
||||||
will automatically prepend the current cursor to explicitly provided
|
|
||||||
parameters, positionally
|
|
||||||
:func:`~odoo.api.cr_uid`
|
|
||||||
will automatically prepend the current cursor and user's id to explictly
|
|
||||||
provided parameters
|
|
||||||
:func:`~odoo.api.cr_uid_ids`
|
|
||||||
will automatically prepend the current cursor, user's id and recordset's
|
|
||||||
ids to explicitly provided parameters
|
|
||||||
:func:`~odoo.api.cr_uid_id`
|
|
||||||
will loop over the current recordset and call the method once for each
|
|
||||||
record, prepending the current cursor, user's id and record's id to
|
|
||||||
explicitly provided parameters.
|
|
||||||
|
|
||||||
.. danger:: the result of this wrapper is *always a list* when calling
|
|
||||||
from a new-API context
|
|
||||||
|
|
||||||
All of these methods have a ``_context``-suffixed version
|
|
||||||
(e.g. :func:`~odoo.api.cr_uid_context`) which also passes the current
|
|
||||||
context *by keyword*.
|
|
||||||
* dual implementations using :func:`~odoo.api.v7` and
|
|
||||||
:func:`~odoo.api.v8` will be ignored as they provide their own "bridging"
|
|
||||||
|
|||||||
@@ -32,11 +32,6 @@ class DecimalPrecision(models.Model):
|
|||||||
res = self.env.cr.fetchone()
|
res = self.env.cr.fetchone()
|
||||||
return res[0] if res else 2
|
return res[0] if res else 2
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def clear_cache(self):
|
|
||||||
""" Deprecated, use `clear_caches` instead. """
|
|
||||||
self.clear_caches()
|
|
||||||
|
|
||||||
@api.model_create_multi
|
@api.model_create_multi
|
||||||
def create(self, vals_list):
|
def create(self, vals_list):
|
||||||
res = super(DecimalPrecision, self).create(vals_list)
|
res = super(DecimalPrecision, self).create(vals_list)
|
||||||
|
|||||||
@@ -283,7 +283,6 @@ class IrActionsActWindowView(models.Model):
|
|||||||
act_window_id = fields.Many2one('ir.actions.act_window', string='Action', ondelete='cascade')
|
act_window_id = fields.Many2one('ir.actions.act_window', string='Action', ondelete='cascade')
|
||||||
multi = fields.Boolean(string='On Multiple Doc.', help="If set to true, the action will not be displayed on the right toolbar of a form view.")
|
multi = fields.Boolean(string='On Multiple Doc.', help="If set to true, the action will not be displayed on the right toolbar of a form view.")
|
||||||
|
|
||||||
@api.model_cr_context
|
|
||||||
def _auto_init(self):
|
def _auto_init(self):
|
||||||
res = super(IrActionsActWindowView, self)._auto_init()
|
res = super(IrActionsActWindowView, self)._auto_init()
|
||||||
tools.create_unique_index(self._cr, 'act_window_view_unique_mode_per_action',
|
tools.create_unique_index(self._cr, 'act_window_view_unique_mode_per_action',
|
||||||
|
|||||||
@@ -765,7 +765,6 @@ class IrActionsReport(models.Model):
|
|||||||
return None
|
return None
|
||||||
return render_func(res_ids, data=data)
|
return render_func(res_ids, data=data)
|
||||||
|
|
||||||
@api.noguess
|
|
||||||
def report_action(self, docids, data=None, config=True):
|
def report_action(self, docids, data=None, config=True):
|
||||||
"""Return an action of type ir.actions.report.
|
"""Return an action of type ir.actions.report.
|
||||||
|
|
||||||
|
|||||||
@@ -300,7 +300,6 @@ class IrAttachment(models.Model):
|
|||||||
mimetype = fields.Char('Mime Type', readonly=True)
|
mimetype = fields.Char('Mime Type', readonly=True)
|
||||||
index_content = fields.Text('Indexed Content', readonly=True, prefetch=False)
|
index_content = fields.Text('Indexed Content', readonly=True, prefetch=False)
|
||||||
|
|
||||||
@api.model_cr_context
|
|
||||||
def _auto_init(self):
|
def _auto_init(self):
|
||||||
res = super(IrAttachment, self)._auto_init()
|
res = super(IrAttachment, self)._auto_init()
|
||||||
tools.create_index(self._cr, 'ir_attachment_res_idx',
|
tools.create_index(self._cr, 'ir_attachment_res_idx',
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ class IrConfigParameter(models.Model):
|
|||||||
('key_uniq', 'unique (key)', 'Key must be unique.')
|
('key_uniq', 'unique (key)', 'Key must be unique.')
|
||||||
]
|
]
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
@mute_logger('odoo.addons.base.models.ir_config_parameter')
|
@mute_logger('odoo.addons.base.models.ir_config_parameter')
|
||||||
def init(self, force=False):
|
def init(self, force=False):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -150,7 +150,6 @@ class IrFilters(models.Model):
|
|||||||
('name_model_uid_unique', 'unique (name, model_id, user_id, action_id)', 'Filter names must be unique'),
|
('name_model_uid_unique', 'unique (name, model_id, user_id, action_id)', 'Filter names must be unique'),
|
||||||
]
|
]
|
||||||
|
|
||||||
@api.model_cr_context
|
|
||||||
def _auto_init(self):
|
def _auto_init(self):
|
||||||
result = super(IrFilters, self)._auto_init()
|
result = super(IrFilters, self)._auto_init()
|
||||||
# Use unique index to implement unique constraint on the lowercase name (not possible using a constraint)
|
# Use unique index to implement unique constraint on the lowercase name (not possible using a constraint)
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ class IrLogging(models.Model):
|
|||||||
func = fields.Char(string='Function', required=True)
|
func = fields.Char(string='Function', required=True)
|
||||||
line = fields.Char(required=True)
|
line = fields.Char(required=True)
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
super(IrLogging, self).init()
|
super(IrLogging, self).init()
|
||||||
self._cr.execute("select 1 from information_schema.constraint_column_usage where table_name = 'ir_logging' and constraint_name = 'ir_logging_write_uid_fkey'")
|
self._cr.execute("select 1 from information_schema.constraint_column_usage where table_name = 'ir_logging' and constraint_name = 'ir_logging_write_uid_fkey'")
|
||||||
|
|||||||
@@ -1191,7 +1191,7 @@ class IrModelAccess(models.Model):
|
|||||||
self._cr.execute(query, (model_name, tuple(group_ids)))
|
self._cr.execute(query, (model_name, tuple(group_ids)))
|
||||||
return bool(self._cr.rowcount)
|
return bool(self._cr.rowcount)
|
||||||
|
|
||||||
@api.model_cr
|
@api.model
|
||||||
def group_names_with_access(self, model_name, access_mode):
|
def group_names_with_access(self, model_name, access_mode):
|
||||||
""" Return the names of visible groups which have been granted
|
""" Return the names of visible groups which have been granted
|
||||||
``access_mode`` on the model ``model_name``.
|
``access_mode`` on the model ``model_name``.
|
||||||
@@ -1288,7 +1288,7 @@ class IrModelAccess(models.Model):
|
|||||||
def unregister_cache_clearing_method(cls, model, method):
|
def unregister_cache_clearing_method(cls, model, method):
|
||||||
cls.__cache_clearing_methods.discard((model, method))
|
cls.__cache_clearing_methods.discard((model, method))
|
||||||
|
|
||||||
@api.model_cr
|
@api.model
|
||||||
def call_cache_clearing_methods(self):
|
def call_cache_clearing_methods(self):
|
||||||
self.invalidate_cache()
|
self.invalidate_cache()
|
||||||
self.check.clear_cache(self) # clear the cache of check function
|
self.check.clear_cache(self) # clear the cache of check function
|
||||||
@@ -1352,7 +1352,6 @@ class IrModelData(models.Model):
|
|||||||
for res in self:
|
for res in self:
|
||||||
res.reference = "%s,%s" % (res.model, res.res_id)
|
res.reference = "%s,%s" % (res.model, res.res_id)
|
||||||
|
|
||||||
@api.model_cr_context
|
|
||||||
def _auto_init(self):
|
def _auto_init(self):
|
||||||
res = super(IrModelData, self)._auto_init()
|
res = super(IrModelData, self)._auto_init()
|
||||||
tools.create_unique_index(self._cr, 'ir_model_data_module_name_uniq_index',
|
tools.create_unique_index(self._cr, 'ir_model_data_module_name_uniq_index',
|
||||||
|
|||||||
@@ -247,7 +247,6 @@ class IrTranslation(models.Model):
|
|||||||
''' the source term is stored on 'src' field '''
|
''' the source term is stored on 'src' field '''
|
||||||
return [('src', operator, value)]
|
return [('src', operator, value)]
|
||||||
|
|
||||||
@api.model_cr_context
|
|
||||||
def _auto_init(self):
|
def _auto_init(self):
|
||||||
res = super(IrTranslation, self)._auto_init()
|
res = super(IrTranslation, self)._auto_init()
|
||||||
# Add separate md5 index on src (no size limit on values, and good performance).
|
# Add separate md5 index on src (no size limit on values, and good performance).
|
||||||
@@ -759,7 +758,6 @@ class IrTranslation(models.Model):
|
|||||||
""" Return a cursor-like object for fast inserting translations """
|
""" Return a cursor-like object for fast inserting translations """
|
||||||
return IrTranslationImport(self)
|
return IrTranslationImport(self)
|
||||||
|
|
||||||
@api.model_cr_context
|
|
||||||
def load_module_terms(self, modules, langs):
|
def load_module_terms(self, modules, langs):
|
||||||
""" Load PO files of the given modules for the given languages. """
|
""" Load PO files of the given modules for the given languages. """
|
||||||
# make sure the given languages are active
|
# make sure the given languages are active
|
||||||
|
|||||||
@@ -101,7 +101,6 @@ class ViewCustom(models.Model):
|
|||||||
return self.browse(view_ids).name_get()
|
return self.browse(view_ids).name_get()
|
||||||
return super(ViewCustom, self)._name_search(name, args=args, operator=operator, limit=limit, name_get_uid=name_get_uid)
|
return super(ViewCustom, self)._name_search(name, args=args, operator=operator, limit=limit, name_get_uid=name_get_uid)
|
||||||
|
|
||||||
@api.model_cr_context
|
|
||||||
def _auto_init(self):
|
def _auto_init(self):
|
||||||
res = super(ViewCustom, self)._auto_init()
|
res = super(ViewCustom, self)._auto_init()
|
||||||
tools.create_index(self._cr, 'ir_ui_view_custom_user_id_ref_id',
|
tools.create_index(self._cr, 'ir_ui_view_custom_user_id_ref_id',
|
||||||
@@ -408,7 +407,6 @@ actual arch.
|
|||||||
"Invalid key: QWeb view should have a key"),
|
"Invalid key: QWeb view should have a key"),
|
||||||
]
|
]
|
||||||
|
|
||||||
@api.model_cr_context
|
|
||||||
def _auto_init(self):
|
def _auto_init(self):
|
||||||
res = super(View, self)._auto_init()
|
res = super(View, self)._auto_init()
|
||||||
tools.create_index(self._cr, 'ir_ui_view_model_type_inherit_id',
|
tools.create_index(self._cr, 'ir_ui_view_model_type_inherit_id',
|
||||||
|
|||||||
@@ -102,7 +102,6 @@ class Company(models.Model):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
for company in self.search([('paperformat_id', '=', False)]):
|
for company in self.search([('paperformat_id', '=', False)]):
|
||||||
paperformat_euro = self.env.ref('base.paperformat_euro', False)
|
paperformat_euro = self.env.ref('base.paperformat_euro', False)
|
||||||
|
|||||||
@@ -695,7 +695,7 @@ class ResConfigSettings(models.TransientModel, ResConfigModuleInstallationMixin)
|
|||||||
model_name, field_name = full_field_name.rsplit('.', 1)
|
model_name, field_name = full_field_name.rsplit('.', 1)
|
||||||
return self.env[model_name].fields_get([field_name])[field_name]['string']
|
return self.env[model_name].fields_get([field_name])[field_name]['string']
|
||||||
|
|
||||||
@api.model_cr_context
|
@api.model
|
||||||
def get_config_warning(self, msg):
|
def get_config_warning(self, msg):
|
||||||
"""
|
"""
|
||||||
Helper: return a Warning exception with the given message where the %(field:xxx)s
|
Helper: return a Warning exception with the given message where the %(field:xxx)s
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ class Lang(models.Model):
|
|||||||
except Exception:
|
except Exception:
|
||||||
raise ValidationError(warning)
|
raise ValidationError(warning)
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def _register_hook(self):
|
def _register_hook(self):
|
||||||
# check that there is at least one active language
|
# check that there is at least one active language
|
||||||
if not self.search_count([]):
|
if not self.search_count([]):
|
||||||
|
|||||||
@@ -241,7 +241,6 @@ class Partner(models.Model):
|
|||||||
('check_name', "CHECK( (type='contact' AND name IS NOT NULL) or (type!='contact') )", 'Contacts require a name.'),
|
('check_name', "CHECK( (type='contact' AND name IS NOT NULL) or (type!='contact') )", 'Contacts require a name.'),
|
||||||
]
|
]
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
self._cr.execute("""SELECT indexname FROM pg_indexes WHERE indexname = 'res_partner_vat_index'""")
|
self._cr.execute("""SELECT indexname FROM pg_indexes WHERE indexname = 'res_partner_vat_index'""")
|
||||||
if not self._cr.fetchone():
|
if not self._cr.fetchone():
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ class LineModel(models.Model):
|
|||||||
base_id = fields.Many2one('test_performance.base', required=True, ondelete='cascade')
|
base_id = fields.Many2one('test_performance.base', required=True, ondelete='cascade')
|
||||||
value = fields.Integer()
|
value = fields.Integer()
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
# line values should be unique per "base" - useful for testing corner cases with unique lines
|
# line values should be unique per "base" - useful for testing corner cases with unique lines
|
||||||
tools.create_unique_index(self._cr, 'test_performance_line_uniq', self._table, ['base_id', 'value'])
|
tools.create_unique_index(self._cr, 'test_performance_line_uniq', self._table, ['base_id', 'value'])
|
||||||
|
|||||||
+3
-309
@@ -33,14 +33,8 @@
|
|||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'Environment',
|
'Environment',
|
||||||
'Meta', 'guess', 'noguess',
|
'Meta',
|
||||||
'model', 'multi',
|
'model', 'multi',
|
||||||
'model_cr', 'model_cr_context',
|
|
||||||
'cr', 'cr_context',
|
|
||||||
'cr_uid', 'cr_uid_context',
|
|
||||||
'cr_uid_id', 'cr_uid_id_context',
|
|
||||||
'cr_uid_ids', 'cr_uid_ids_context',
|
|
||||||
'cr_uid_records', 'cr_uid_records_context',
|
|
||||||
'constrains', 'depends', 'onchange', 'returns',
|
'constrains', 'depends', 'onchange', 'returns',
|
||||||
'call_kw',
|
'call_kw',
|
||||||
]
|
]
|
||||||
@@ -48,7 +42,7 @@ __all__ = [
|
|||||||
import logging
|
import logging
|
||||||
from collections import defaultdict, Mapping
|
from collections import defaultdict, Mapping
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from inspect import currentframe, getargspec
|
from inspect import getargspec
|
||||||
from pprint import pformat
|
from pprint import pformat
|
||||||
from weakref import WeakSet
|
from weakref import WeakSet
|
||||||
|
|
||||||
@@ -69,12 +63,8 @@ _logger = logging.getLogger(__name__)
|
|||||||
#
|
#
|
||||||
# On wrapping method only:
|
# On wrapping method only:
|
||||||
# - method._api: decorator function, used for re-applying decorator
|
# - method._api: decorator function, used for re-applying decorator
|
||||||
# - method._orig: original method
|
|
||||||
#
|
#
|
||||||
|
|
||||||
WRAPPED_ATTRS = ('__module__', '__name__', '__doc__', '_constrains',
|
|
||||||
'_depends', '_onchange', '_returns', 'clear_cache')
|
|
||||||
|
|
||||||
INHERITED_ATTRS = ('_returns',)
|
INHERITED_ATTRS = ('_returns',)
|
||||||
|
|
||||||
|
|
||||||
@@ -82,6 +72,7 @@ class Params(object):
|
|||||||
def __init__(self, args, kwargs):
|
def __init__(self, args, kwargs):
|
||||||
self.args = args
|
self.args = args
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
params = []
|
params = []
|
||||||
for arg in self.args:
|
for arg in self.args:
|
||||||
@@ -106,13 +97,6 @@ class Meta(type):
|
|||||||
# make the method inherit from decorators
|
# make the method inherit from decorators
|
||||||
value = propagate(getattr(parent, key, None), value)
|
value = propagate(getattr(parent, key, None), value)
|
||||||
|
|
||||||
# guess calling convention if none is given
|
|
||||||
if not hasattr(value, '_api'):
|
|
||||||
try:
|
|
||||||
value = guess(value)
|
|
||||||
except TypeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if (getattr(value, '_api', None) or '').startswith('cr'):
|
if (getattr(value, '_api', None) or '').startswith('cr'):
|
||||||
_logger.warning("Deprecated method %s.%s in module %s", name, key, attrs.get('__module__'))
|
_logger.warning("Deprecated method %s.%s in module %s", name, key, attrs.get('__module__'))
|
||||||
|
|
||||||
@@ -324,50 +308,6 @@ def multi(method):
|
|||||||
return method
|
return method
|
||||||
|
|
||||||
|
|
||||||
def model_cr(method):
|
|
||||||
""" Decorate a record-style method where ``self`` is a recordset, but its
|
|
||||||
contents is not relevant, only the model is. Such a method::
|
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def method(self, args):
|
|
||||||
...
|
|
||||||
|
|
||||||
may be called in both record and traditional styles, like::
|
|
||||||
|
|
||||||
# recs = model.browse(cr, uid, ids, context)
|
|
||||||
recs.method(args)
|
|
||||||
|
|
||||||
model.method(cr, args)
|
|
||||||
|
|
||||||
Notice that no ``uid``, ``ids``, ``context`` are passed to the method in
|
|
||||||
the traditional style.
|
|
||||||
"""
|
|
||||||
method._api = 'model_cr'
|
|
||||||
return method
|
|
||||||
|
|
||||||
|
|
||||||
def model_cr_context(method):
|
|
||||||
""" Decorate a record-style method where ``self`` is a recordset, but its
|
|
||||||
contents is not relevant, only the model is. Such a method::
|
|
||||||
|
|
||||||
@api.model_cr_context
|
|
||||||
def method(self, args):
|
|
||||||
...
|
|
||||||
|
|
||||||
may be called in both record and traditional styles, like::
|
|
||||||
|
|
||||||
# recs = model.browse(cr, uid, ids, context)
|
|
||||||
recs.method(args)
|
|
||||||
|
|
||||||
model.method(cr, args, context=context)
|
|
||||||
|
|
||||||
Notice that no ``uid``, ``ids`` are passed to the method in the
|
|
||||||
traditional style.
|
|
||||||
"""
|
|
||||||
method._api = 'model_cr_context'
|
|
||||||
return method
|
|
||||||
|
|
||||||
|
|
||||||
_create_logger = logging.getLogger(__name__ + '.create')
|
_create_logger = logging.getLogger(__name__ + '.create')
|
||||||
|
|
||||||
|
|
||||||
@@ -412,252 +352,6 @@ def model_create_multi(method):
|
|||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
def cr(method):
|
|
||||||
""" Decorate a traditional-style method that takes ``cr`` as a parameter.
|
|
||||||
Such a method may be called in both record and traditional styles, like::
|
|
||||||
|
|
||||||
# recs = model.browse(cr, uid, ids, context)
|
|
||||||
recs.method(args)
|
|
||||||
|
|
||||||
model.method(cr, args)
|
|
||||||
"""
|
|
||||||
method._api = 'cr'
|
|
||||||
return method
|
|
||||||
|
|
||||||
|
|
||||||
def cr_context(method):
|
|
||||||
""" Decorate a traditional-style method that takes ``cr``, ``context`` as parameters. """
|
|
||||||
method._api = 'cr_context'
|
|
||||||
return method
|
|
||||||
|
|
||||||
|
|
||||||
def cr_uid(method):
|
|
||||||
""" Decorate a traditional-style method that takes ``cr``, ``uid`` as parameters. """
|
|
||||||
method._api = 'cr_uid'
|
|
||||||
return method
|
|
||||||
|
|
||||||
|
|
||||||
def cr_uid_context(method):
|
|
||||||
""" Decorate a traditional-style method that takes ``cr``, ``uid``, ``context`` as
|
|
||||||
parameters. Such a method may be called in both record and traditional
|
|
||||||
styles, like::
|
|
||||||
|
|
||||||
# recs = model.browse(cr, uid, ids, context)
|
|
||||||
recs.method(args)
|
|
||||||
|
|
||||||
model.method(cr, uid, args, context=context)
|
|
||||||
"""
|
|
||||||
method._api = 'cr_uid_context'
|
|
||||||
return method
|
|
||||||
|
|
||||||
|
|
||||||
def cr_uid_id(method):
|
|
||||||
""" Decorate a traditional-style method that takes ``cr``, ``uid``, ``id`` as
|
|
||||||
parameters. Such a method may be called in both record and traditional
|
|
||||||
styles. In the record style, the method automatically loops on records.
|
|
||||||
"""
|
|
||||||
method._api = 'cr_uid_id'
|
|
||||||
return method
|
|
||||||
|
|
||||||
|
|
||||||
def cr_uid_id_context(method):
|
|
||||||
""" Decorate a traditional-style method that takes ``cr``, ``uid``, ``id``,
|
|
||||||
``context`` as parameters. Such a method::
|
|
||||||
|
|
||||||
@api.cr_uid_id
|
|
||||||
def method(self, cr, uid, id, args, context=None):
|
|
||||||
...
|
|
||||||
|
|
||||||
may be called in both record and traditional styles, like::
|
|
||||||
|
|
||||||
# rec = model.browse(cr, uid, id, context)
|
|
||||||
rec.method(args)
|
|
||||||
|
|
||||||
model.method(cr, uid, id, args, context=context)
|
|
||||||
"""
|
|
||||||
method._api = 'cr_uid_id_context'
|
|
||||||
return method
|
|
||||||
|
|
||||||
|
|
||||||
def cr_uid_ids(method):
|
|
||||||
""" Decorate a traditional-style method that takes ``cr``, ``uid``, ``ids`` as
|
|
||||||
parameters. Such a method may be called in both record and traditional
|
|
||||||
styles.
|
|
||||||
"""
|
|
||||||
method._api = 'cr_uid_ids'
|
|
||||||
return method
|
|
||||||
|
|
||||||
|
|
||||||
def cr_uid_ids_context(method):
|
|
||||||
""" Decorate a traditional-style method that takes ``cr``, ``uid``, ``ids``,
|
|
||||||
``context`` as parameters. Such a method::
|
|
||||||
|
|
||||||
@api.cr_uid_ids_context
|
|
||||||
def method(self, cr, uid, ids, args, context=None):
|
|
||||||
...
|
|
||||||
|
|
||||||
may be called in both record and traditional styles, like::
|
|
||||||
|
|
||||||
# recs = model.browse(cr, uid, ids, context)
|
|
||||||
recs.method(args)
|
|
||||||
|
|
||||||
model.method(cr, uid, ids, args, context=context)
|
|
||||||
|
|
||||||
It is generally not necessary, see :func:`guess`.
|
|
||||||
"""
|
|
||||||
method._api = 'cr_uid_ids_context'
|
|
||||||
return method
|
|
||||||
|
|
||||||
|
|
||||||
def cr_uid_records(method):
|
|
||||||
""" Decorate a traditional-style method that takes ``cr``, ``uid``, a
|
|
||||||
recordset of model ``self`` as parameters. Such a method::
|
|
||||||
|
|
||||||
@api.cr_uid_records
|
|
||||||
def method(self, cr, uid, records, args):
|
|
||||||
...
|
|
||||||
|
|
||||||
may be called in both record and traditional styles, like::
|
|
||||||
|
|
||||||
# records = model.browse(cr, uid, ids, context)
|
|
||||||
records.method(args)
|
|
||||||
|
|
||||||
model.method(cr, uid, records, args)
|
|
||||||
"""
|
|
||||||
method._api = 'cr_uid_records'
|
|
||||||
return method
|
|
||||||
|
|
||||||
|
|
||||||
def cr_uid_records_context(method):
|
|
||||||
""" Decorate a traditional-style method that takes ``cr``, ``uid``, a
|
|
||||||
recordset of model ``self``, ``context`` as parameters. Such a method::
|
|
||||||
|
|
||||||
@api.cr_uid_records_context
|
|
||||||
def method(self, cr, uid, records, args, context=None):
|
|
||||||
...
|
|
||||||
|
|
||||||
may be called in both record and traditional styles, like::
|
|
||||||
|
|
||||||
# records = model.browse(cr, uid, ids, context)
|
|
||||||
records.method(args)
|
|
||||||
|
|
||||||
model.method(cr, uid, records, args, context=context)
|
|
||||||
"""
|
|
||||||
method._api = 'cr_uid_records_context'
|
|
||||||
return method
|
|
||||||
|
|
||||||
|
|
||||||
def v7(method_v7):
|
|
||||||
""" Decorate a method that supports the old-style api only. A new-style api
|
|
||||||
may be provided by redefining a method with the same name and decorated
|
|
||||||
with :func:`~.v8`::
|
|
||||||
|
|
||||||
@api.v7
|
|
||||||
def foo(self, cr, uid, ids, context=None):
|
|
||||||
...
|
|
||||||
|
|
||||||
@api.v8
|
|
||||||
def foo(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
Special care must be taken if one method calls the other one, because
|
|
||||||
the method may be overridden! In that case, one should call the method
|
|
||||||
from the current class (say ``MyClass``), for instance::
|
|
||||||
|
|
||||||
@api.v7
|
|
||||||
def foo(self, cr, uid, ids, context=None):
|
|
||||||
# Beware: records.foo() may call an overriding of foo()
|
|
||||||
records = self.browse(cr, uid, ids, context)
|
|
||||||
return MyClass.foo(records)
|
|
||||||
|
|
||||||
Note that the wrapper method uses the docstring of the first method.
|
|
||||||
"""
|
|
||||||
# retrieve method_v8 from the caller's frame
|
|
||||||
frame = currentframe().f_back
|
|
||||||
return frame.f_locals.get(method_v7.__name__, method_v7)
|
|
||||||
|
|
||||||
|
|
||||||
def v8(method_v8):
|
|
||||||
""" Decorate a method that supports the new-style api only. An old-style api
|
|
||||||
may be provided by redefining a method with the same name and decorated
|
|
||||||
with :func:`~.v7`::
|
|
||||||
|
|
||||||
@api.v8
|
|
||||||
def foo(self):
|
|
||||||
...
|
|
||||||
|
|
||||||
@api.v7
|
|
||||||
def foo(self, cr, uid, ids, context=None):
|
|
||||||
...
|
|
||||||
|
|
||||||
Note that the wrapper method uses the docstring of the first method.
|
|
||||||
"""
|
|
||||||
if method_v8.__name__ == 'read':
|
|
||||||
return multi(method_v8)
|
|
||||||
method_v8._api = 'v8'
|
|
||||||
return method_v8
|
|
||||||
|
|
||||||
|
|
||||||
def noguess(method):
|
|
||||||
""" Decorate a method to prevent any effect from :func:`guess`. """
|
|
||||||
method._api = None
|
|
||||||
return method
|
|
||||||
|
|
||||||
|
|
||||||
def guess(method):
|
|
||||||
""" Decorate ``method`` to make it callable in both traditional and record
|
|
||||||
styles. This decorator is applied automatically by the model's
|
|
||||||
metaclass, and has no effect on already-decorated methods.
|
|
||||||
|
|
||||||
The API style is determined by heuristics on the parameter names: ``cr``
|
|
||||||
or ``cursor`` for the cursor, ``uid`` or ``user`` for the user id,
|
|
||||||
``id`` or ``ids`` for a list of record ids, and ``context`` for the
|
|
||||||
context dictionary. If a traditional API is recognized, one of the
|
|
||||||
decorators :func:`cr`, :func:`cr_context`, :func:`cr_uid`,
|
|
||||||
:func:`cr_uid_context`, :func:`cr_uid_id`, :func:`cr_uid_id_context`,
|
|
||||||
:func:`cr_uid_ids`, :func:`cr_uid_ids_context` is applied on the method.
|
|
||||||
|
|
||||||
Method calls are considered traditional style when their first parameter
|
|
||||||
is a database cursor.
|
|
||||||
"""
|
|
||||||
if hasattr(method, '_api'):
|
|
||||||
return method
|
|
||||||
|
|
||||||
# introspection on argument names to determine api style
|
|
||||||
args, vname, kwname, defaults = getargspec(method)
|
|
||||||
names = tuple(args) + (None,) * 4
|
|
||||||
|
|
||||||
if names[0] == 'self':
|
|
||||||
if names[1] in ('cr', 'cursor'):
|
|
||||||
if names[2] in ('uid', 'user'):
|
|
||||||
if names[3] == 'ids':
|
|
||||||
if 'context' in names or kwname:
|
|
||||||
return cr_uid_ids_context(method)
|
|
||||||
else:
|
|
||||||
return cr_uid_ids(method)
|
|
||||||
elif names[3] == 'id' or names[3] == 'res_id':
|
|
||||||
if 'context' in names or kwname:
|
|
||||||
return cr_uid_id_context(method)
|
|
||||||
else:
|
|
||||||
return cr_uid_id(method)
|
|
||||||
elif 'context' in names or kwname:
|
|
||||||
return cr_uid_context(method)
|
|
||||||
else:
|
|
||||||
return cr_uid(method)
|
|
||||||
elif 'context' in names:
|
|
||||||
return cr_context(method)
|
|
||||||
else:
|
|
||||||
return cr(method)
|
|
||||||
|
|
||||||
# no wrapping by default
|
|
||||||
return noguess(method)
|
|
||||||
|
|
||||||
|
|
||||||
def expected(decorator, func):
|
|
||||||
""" Decorate ``func`` with ``decorator`` if ``func`` is not wrapped yet. """
|
|
||||||
return decorator(func) if not hasattr(func, '_api') else func
|
|
||||||
|
|
||||||
|
|
||||||
def _call_kw_model(method, self, args, kwargs):
|
def _call_kw_model(method, self, args, kwargs):
|
||||||
context, args, kwargs = split_context(method, args, kwargs)
|
context, args, kwargs = split_context(method, args, kwargs)
|
||||||
recs = self.with_context(context or {})
|
recs = self.with_context(context or {})
|
||||||
|
|||||||
+1
-13
@@ -298,7 +298,6 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@api.model_cr_context
|
|
||||||
def _reflect(self):
|
def _reflect(self):
|
||||||
""" Reflect the model and its fields in the models 'ir.model' and
|
""" Reflect the model and its fields in the models 'ir.model' and
|
||||||
'ir.model.fields'. Also create entries in 'ir.model.data' if the key
|
'ir.model.fields'. Also create entries in 'ir.model.data' if the key
|
||||||
@@ -2281,7 +2280,6 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
|
|||||||
else:
|
else:
|
||||||
return '"%s"."%s"' % (alias, fname)
|
return '"%s"."%s"' % (alias, fname)
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def _parent_store_compute(self):
|
def _parent_store_compute(self):
|
||||||
""" Compute parent_path field from scratch. """
|
""" Compute parent_path field from scratch. """
|
||||||
if not self._parent_store:
|
if not self._parent_store:
|
||||||
@@ -2320,7 +2318,6 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
|
|||||||
self.invalidate_cache(['parent_path'])
|
self.invalidate_cache(['parent_path'])
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def _check_removed_columns(self, log=False):
|
def _check_removed_columns(self, log=False):
|
||||||
# iterate on the database columns to drop the NOT NULL constraints of
|
# iterate on the database columns to drop the NOT NULL constraints of
|
||||||
# fields which were required but have been removed (or will be added by
|
# fields which were required but have been removed (or will be added by
|
||||||
@@ -2343,7 +2340,6 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
|
|||||||
if row['attnotnull']:
|
if row['attnotnull']:
|
||||||
tools.drop_not_null(cr, self._table, row['attname'])
|
tools.drop_not_null(cr, self._table, row['attname'])
|
||||||
|
|
||||||
@api.model_cr_context
|
|
||||||
def _init_column(self, column_name):
|
def _init_column(self, column_name):
|
||||||
""" Initialize the value of the given column for existing rows. """
|
""" Initialize the value of the given column for existing rows. """
|
||||||
# get the default value; ideally, we should use default_get(), but it
|
# get the default value; ideally, we should use default_get(), but it
|
||||||
@@ -2375,7 +2371,6 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
|
|||||||
self.env.cr.execute('SELECT 1 FROM "%s" LIMIT 1' % self._table)
|
self.env.cr.execute('SELECT 1 FROM "%s" LIMIT 1' % self._table)
|
||||||
return self.env.cr.rowcount
|
return self.env.cr.rowcount
|
||||||
|
|
||||||
@api.model_cr_context
|
|
||||||
def _auto_init(self):
|
def _auto_init(self):
|
||||||
""" Initialize the database schema of ``self``:
|
""" Initialize the database schema of ``self``:
|
||||||
- create the corresponding table,
|
- create the corresponding table,
|
||||||
@@ -2446,14 +2441,12 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
|
|||||||
if parent_path_compute:
|
if parent_path_compute:
|
||||||
self._parent_store_compute()
|
self._parent_store_compute()
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def init(self):
|
def init(self):
|
||||||
""" This method is called after :meth:`~._auto_init`, and may be
|
""" This method is called after :meth:`~._auto_init`, and may be
|
||||||
overridden to create or modify a model's database schema.
|
overridden to create or modify a model's database schema.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def _create_parent_columns(self):
|
def _create_parent_columns(self):
|
||||||
tools.create_column(self._cr, self._table, 'parent_path', 'VARCHAR')
|
tools.create_column(self._cr, self._table, 'parent_path', 'VARCHAR')
|
||||||
if 'parent_path' not in self._fields:
|
if 'parent_path' not in self._fields:
|
||||||
@@ -2461,7 +2454,6 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
|
|||||||
elif not self._fields['parent_path'].index:
|
elif not self._fields['parent_path'].index:
|
||||||
_logger.error('parent_path field on model %s must be indexed! Add index=True to the field definition)', self._name)
|
_logger.error('parent_path field on model %s must be indexed! Add index=True to the field definition)', self._name)
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def _add_sql_constraints(self):
|
def _add_sql_constraints(self):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -2489,7 +2481,6 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
|
|||||||
else:
|
else:
|
||||||
process(key, definition)
|
process(key, definition)
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def _execute_sql(self):
|
def _execute_sql(self):
|
||||||
""" Execute the SQL code from the _sql attribute (if any)."""
|
""" Execute the SQL code from the _sql attribute (if any)."""
|
||||||
if hasattr(self, "_sql"):
|
if hasattr(self, "_sql"):
|
||||||
@@ -4527,7 +4518,6 @@ Fields:
|
|||||||
"""
|
"""
|
||||||
return cls._transient
|
return cls._transient
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def _transient_clean_rows_older_than(self, seconds):
|
def _transient_clean_rows_older_than(self, seconds):
|
||||||
assert self._transient, "Model %s is not transient, it cannot be vacuumed!" % self._name
|
assert self._transient, "Model %s is not transient, it cannot be vacuumed!" % self._name
|
||||||
# Never delete rows used in last 5 minutes
|
# Never delete rows used in last 5 minutes
|
||||||
@@ -4539,7 +4529,6 @@ Fields:
|
|||||||
ids = [x[0] for x in self._cr.fetchall()]
|
ids = [x[0] for x in self._cr.fetchall()]
|
||||||
self.sudo().browse(ids).unlink()
|
self.sudo().browse(ids).unlink()
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def _transient_clean_old_rows(self, max_count):
|
def _transient_clean_old_rows(self, max_count):
|
||||||
# Check how many rows we have in the table
|
# Check how many rows we have in the table
|
||||||
self._cr.execute("SELECT count(*) AS row_count FROM " + self._table)
|
self._cr.execute("SELECT count(*) AS row_count FROM " + self._table)
|
||||||
@@ -4682,7 +4671,6 @@ Fields:
|
|||||||
for record in self:
|
for record in self:
|
||||||
record.active = not record.active
|
record.active = not record.active
|
||||||
|
|
||||||
@api.model_cr
|
|
||||||
def _register_hook(self):
|
def _register_hook(self):
|
||||||
""" stuff to do right after the registry is built """
|
""" stuff to do right after the registry is built """
|
||||||
pass
|
pass
|
||||||
@@ -4714,7 +4702,7 @@ Fields:
|
|||||||
origin = getattr(cls, name)
|
origin = getattr(cls, name)
|
||||||
method.origin = origin
|
method.origin = origin
|
||||||
# propagate decorators from origin to method, and apply api decorator
|
# propagate decorators from origin to method, and apply api decorator
|
||||||
wrapped = api.guess(api.propagate(origin, method))
|
wrapped = api.propagate(origin, method)
|
||||||
wrapped.origin = origin
|
wrapped.origin = origin
|
||||||
setattr(cls, name, wrapped)
|
setattr(cls, name, wrapped)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user