[IMP] api: remove deprecated decorators

This commit is contained in:
Raphael Collet
2019-07-08 13:51:35 +00:00
parent fa5037650d
commit c552fb7a61
54 changed files with 7 additions and 424 deletions
@@ -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:
-1
View File
@@ -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")
-2
View File
@@ -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',
-1
View File
@@ -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():
-1
View File
@@ -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 (
-1
View File
@@ -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)""" % (
-1
View File
@@ -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)""" % (
-1
View File
@@ -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)
-1
View File
@@ -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():
-1
View File
@@ -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():
-1
View File
@@ -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("""
-1
View File
@@ -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())
-1
View File
@@ -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)
-1
View File
@@ -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 = """
-1
View File
@@ -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')
-1
View File
@@ -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
-39
View File
@@ -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)
-1
View File
@@ -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.
-1
View File
@@ -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):
""" """
-1
View File
@@ -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)
-1
View File
@@ -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'")
+2 -3
View File
@@ -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
-2
View File
@@ -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',
-1
View File
@@ -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)
+1 -1
View File
@@ -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
-1
View File
@@ -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([]):
-1
View File
@@ -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
View File
@@ -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
View File
@@ -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)