Nâng cấp addon lên Odoo 19 - tổng hợp thay đổi kỹ thuật

  Oct 15, 2025      2m      0   
 

Tut 21: Nâng cấp addon các phiên bản cũ lên Odoo 19

Nâng cấp addon lên Odoo 19 - tổng hợp thay đổi kỹ thuật

Odoo Tut 21: Nâng cấp addon lên Odoo 19 - tổng hợp thay đổi kỹ thuật

Bài viết này sẽ hướng dẫn cách nâng cấp addon Odoo từ phiên bản Odoo 18 lên phiên bản mới nhất Odoo 19. Như ta đã biết, phiên bản nâng cấp của Odoo thường có những thay đổi về mặt kỹ thuật dẫn đến addon cũ không thể chạy được trên phiên bản mới. Các "breaking changes" này sẽ được tổng hợp trong bài viết này.

Các thay đổi về cách lập trình trong Odoo 19 sẽ chia theo các mục sau:

  • Cấu hình: các cấu hình mới trong etc/odoo.conf
  • Model:
    • Lỗi @api.returns
    • Cảnh báo thay đổi "_sql_constraints" thành "model.Constraint"
    • Cảnh báo thay đổi "odoo.osv" thành "odoo.fields.Domain"
    • Bổ sung "@api.private"
  • View:
    • Lỗi attribute "expand" và "string" trong thẻ "group"
    • Lỗi thẻ name "card" trong thẻ kanban
  • Controller:
    • Lỗi route type "json"
    • Cảnh báo thay đổi "request.cr" và "request.context" thành "request.env.cr" và "request.env.context"
    • XML-RPC và JSON-RPC Deprecation

Bổ sung cấu hình Odoo 19

Các cấu hình mới được thêm vào từ Odoo 19:

  • reinit: Cho phép khởi tạo lại một hoặc nhiều module (danh sách phân cách bằng dấu phẩy), yêu cầu phải cấu hình tương ứng "db_name"
  • with_demo: Cài đặt dữ liệu demo trong database mới được tạo
  • pre_upgrade_scripts: Chạy các script nâng cấp trước khi load bất kỳ module nào, khi cấu hình các module cập nhật tại "update"
  • db_app_name: Chỉ định tên ứng dụng trong database, {pid} sẽ được thay thế bằng process ID
  • limit_time_worker_cron: Thời gian tối đa (tính bằng giây) mà một cron thread/worker tồn tại trước khi được khởi động lại. Thiết lập giá trị 0 để vô hiệu hóa (mặc định: 0)

etc/odoo.conf

; ------
; --reinit | reinitialize one or more modules (comma-separated list), requires -d
; ------
; reinit =


; ------
; --with-demo | install demo data in new databases
; ------
; with_demo =


; ------
; --pre-upgrade-scripts | Run specific upgrade scripts before loading any module when -u is provided.
; ------
; pre_upgrade_scripts =


; ------
; --db_app_name | specify the application name in the database, {pid} is substituted by the process pid
; ------
; db_app_name = odoo-{pid}

; ------
; --limit-time-worker-cron | type = int | Maximum time a cron thread/worker stays alive before it is restarted. Set to 0 to disable. (default: 0)
; ------
; limit_time_worker_cron = 0

Các thay đổi lập trình Model trong Odoo 19

  • Lỗi @api.returns
  • Cảnh báo thay đổi "_sql_constraints" thành "model.Constraint"
  • Cảnh báo thay đổi "odoo.osv" thành "odoo.fields.Domain"
  • Bổ sung "@api.private"

Lỗi @api.returns

Trong Odoo 19, decorator @api.returns đã bị loại bỏ.

    @api.returns("self", lambda value: value.id)
     ^^^^^^^^^^^
AttributeError: module 'odoo.api' has no attribute 'returns'

Cách sửa rất đơn giản, ta chỉ cần xóa decorator @api.returns này đi.

# Cách cũ (ERROR)
@api.returns('self')      # <-- xóa decorator này đi trong Odoo 19
def _default_employee_get(self):
  return self.env.user.employee_id

# Cách mới
def _default_employee_get(self):
  return self.env.user.employee_id

Cảnh báo thay đổi "_sql_constraints" thành "model.Constraint"

Cảnh báo khi code trong addon dùng _sql_constraints:

Model attribute '_sql_constraints' is no longer supported, please define model.Constraint on the model.

Cách sửa cảnh báo _sql_constraints trong Odoo 19 ta sẽ code theo cách mới bằng cách sử dụng model.Constraint.

# Cách cũ (WARNING)
_sql_constraints = [(
  'name_uniq', "unique(name, applicability, country_id)", 
  "A tag with the same name and applicability already exists in this country."
)]

# Cách mới
_name_uniq = models.Constraint(
  'unique(name, applicability, country_id)',
  'A tag with the same name and applicability already exists in this country.',
)

Cảnh báo thay đổi "odoo.osv" thành "odoo.fields.Domain"

odoo.osv đã bị deprecated, sắp có thể bị bỏ đi trong các phiên bản Odoo trong tương lai.

DeprecationWarning: Since 19.0, odoo.osv is deprecated use odoo.fields.Domain

Ta cần thay đổi thành odoo.fields.Domain.

# Cách cũ (WARNING)
from odoo.osv import osv
#...
domain = expression.AND([name_domain, domain])


# Cách mới
from odoo.fields import Domain
#...
domain = Domain.AND([search_domain, domain])

Bổ sung "@api.private"

Trong Odoo 19, ta có thể sử dụng decorator @api.private để đánh dấu các method là private, không thể được gọi qua RPC. Hiện decorator này chưa được sử dụng nhiều trong code base của Odoo 19.

# ...
class AccountMove(models.Model):
    # ...
    @api.private
    def get_portal_last_transaction(self):
        self.ensure_one()
        return self.with_context(active_test=False).sudo().transaction_ids._get_last()

Các thay đổi lập trình View trong Odoo 19

  • Lỗi attribute "expand" và "string" trong thẻ "group"
  • Lỗi thẻ name "card" trong thẻ kanban

Lỗi attribute "expand" và "string" trong thẻ "group"

# Cách cũ (ERROR)
<record id="view_account_analytic_account_search" model="ir.ui.view">
    <!-- ... -->
    <field name="arch" type="xml">
        <search string="Analytic Account">
            <!-- ... -->
            <group expand="0" string="Group By...">
                <filter string="Associated Partner" name="associatedpartner" domain="[]" context="{'group_by': 'partner_id'}"/>
            </group>
        </search>
    </field>
</record>

# Cách mới
<record id="view_account_analytic_account_search" model="ir.ui.view">
    <!-- ... -->
    <field name="arch" type="xml">
        <search string="Analytic Account">
            <!-- ... -->
            <group>     <!-- Bỏ 2 thuộc tính "expand" và "string" trong Odoo 19 để tránh báo lỗi -->
                <filter string="Associated Partner" name="associatedpartner" domain="[]" context="{'group_by': 'partner_id'}"/>
            </group>
        </search>
    </field>
</record>

Lỗi thẻ name "card" trong thẻ kanban

Trong Odoo 19, bắt buộc phải có thẻ <t t-name="card"> trong thẻ <kanban>. Nếu hiện thực kanban của bạn chưa cập nhật theo những phiên bản gần đây, có thể sẽ bị báo lỗi.

<kanban>
    <!-- ... -->
    <templates>
        <t t-name="card">   <!-- Odoo 19 bắt buộc chỗ này -->
          <!-- ... -->
        </t>
    </templates>
</kanban>

Các thay đổi lập trình Controller trong Odoo 19

  • Lỗi route type "json"
  • Cảnh báo thay đổi "request.cr" và "request.context" thành "request.env.cr" và "request.env.context"
  • XML-RPC và JSON-RPC Deprecation

Lỗi route type "json"

Lỗi khi controller vẫn dùng type json:

DeprecationWarning: Since 19.0, @route(type='json') is a deprecated alias to @route(type='jsonrpc')

Trong decorator @route thay đổi từ type='json' thành type='jsonrpc'

# Cách cũ (ERROR)
@route('/sms/status', type='json', auth='public')

# Cách mới
@route('/sms/status', type='jsonrpc', auth='public')

Cảnh báo thay đổi "request.cr" và "request.context" thành "request.env.cr" và "request.env.context"

Thông báo request.crrequest.context sắp bị bỏ đi ở phiên bản sau trong tương lai.

DeprecationWarning: Since 19.0, use request.env.cr directly

DeprecationWarning: Since 19.0, use request.env.context directly

Ta đổi thành request.env.crrequest.env.context

# Cách cũ (WARNING)
env = api.Environment(request.cr, SUPERUSER_ID, request.context)

# Cách mới
env = api.Environment(request.env.cr, SUPERUSER_ID, request.env.context)

XML-RPC và JSON-RPC Deprecation

Đây là thay đổi lớn nhất trong Odoo 19: XML-RPC và JSON-RPC endpoints sẽ bị deprecated và sẽ bị loại bỏ hoàn toàn trong Odoo 20 (từ 2026) => tham khảo: https://www.odoo.com/documentation/19.0/developer/reference/external_rpc_api.html

Thay thế XML-RPC và JSON-RPC sẽ là JSON-2 API => tham khảo: https://www.odoo.com/documentation/19.0/developer/reference/external_api.html

Hãy tham gia group Facebook để trao đổi và học hỏi thêm về Odoo nhé các bạn => Khám phá Odoo: https://facebook.com/groups/odoo-dev

Cài đặt Odoo:

Danh sách bài viết series Odoo:

Tham gia ngay group trên Facebook để cùng thảo luận với đồng bọn nhé:

Khám phá Odoo