Thừa kế controller trong Odoo

  Jun 17, 2020      2m
   

Tut 8: Thừa kế controller trong Odoo

Thừa kế controller trong Odoo

Trước khi xem bài viết này, bạn vui lòng hoàn thành hướng dẫn ở Tut 7 - Thừa kế view trong Odoo hoặc download mã nguồn ở cuối bài Tut 7.

Bài viết này sẽ hướng dẫn bạn:

  • Thừa kế controller trong Odoo.
  • Chỉnh sửa controller của Odoo bằng cách thừa kế.

Mã nguồn hoàn chỉnh cho bài viết Tut 8 này được đính kèm ở cuối bài viết.

Thừa kế controller trong Odoo

Để hiện thực controller trong Odoo thực chất ta đã phải thực hiện thừa kế lớp odoo.http.Controller (xem lại Tut 5: Controller trong Odoo). Việc thừa kế các built-in controller của Odoo hoặc của một controller trong custom module cho phép ta "override" phương thức để thay đổi hành vi, hoặc kết quả trả về của controller / api.

Như ghi chú trước Minh đã nhắc, ta NÊN thừa kế và override phương thức để chỉnh sửa (built-in) module. Không thực hiện sửa code trực tiếp ở module gốc, vì đây có thể gọi là "bad practice" :).

Rồi, vậy là mình đã hiểu vì sao việc thừa kế trong mã nguồn mở là quan trọng. Tiếp theo sẽ là hướng dẫn cụ thể cho việc thừa kế controller trong Odoo.

Override phương thức của controller

Minh xin phép nhắc lại 2 API đã hiện thực ở Tut 5:

  • API /foo: trả về chuỗi "Welcome to 'foo' API!"
  • API /bar: trả về json {"content": "Welcome to 'bar' API!"}
#...
class MyPetAPI(odoo.http.Controller):
    @odoo.http.route('/foo', auth='public')
    def foo_handler(self):
        return "Welcome to 'foo' API!"

    @odoo.http.route('/bar', auth='public')
    def bar_handler(self):
        return json.dumps({
            "content": "Welcome to 'bar' API!"
        })
#...

Bây giờ, ta sẽ tiến hành override foo_handlerbar_handler để nó trả về kết quả khác thay vì như controller gốc đã hiện thực ở module mypet. Trước tiên, ta tạo thư mục controller trong module mypet_plus và include vào init.

mypet_plus/__init__.py

from . import models
from . import controllers # <- them dong nay

Hiện thực override bằng cách thừa kế như 2 file sau:

mypet_plus/controllers/__init__.py

from . import main

mypet_plus/controllers/main.py (file Python hiện thực controller con thừa kế không nhất thiết giống tên trong controller gốc)

import odoo
import json
import logging
_logger = logging.getLogger(__name__)

class MyPetAPIInherit(odoo.addons.mypet.controllers.main.MyPetAPI):
    @odoo.http.route()
    def foo_handler(self):
        return "New 'foo' API!"

    @odoo.http.route('/bar2')
    def bar_handler(self):
        return json.dumps({
            "content": "New 'bar' API!"
        })

    @odoo.http.route()
    def pet_handler(self, dbname, id, **kw):
        _logger.warning("Pet handler called~")
        result = super(MyPetAPIInherit, self).pet_handler(dbname, id)
        _logger.warning("Post processing~")
        return result

Giải thích:

  • odoo.addons.mypet.controllers.main.MyPetAPI: trỏ thẳng đến class MyPetAPI trong module mypet. Bạn cũng có thể import bằng cách from odoo.addons.mypet.controllers.main import MyPetAPI, sau đó ta thừa kế class MyPetAPIInherit(MyPetAPI):.
  • @odoo.http.route(): không đặc tả tham số sẽ giữ routing gốc trong controller cha.
  • Đặc tả tham số trong decorator @route(): Odoo sẽ override routing gốc. Trong ví dụ cụ thể trên, mình đã override hẳn URL của API bar.
  • Ta có thể thêm code xử lý, trước / sau khi gọi phương thức gốc trong class cha. Xem cách làm của phương thức pet_handler trong code mẫu trên.

Do ta đã sửa file Python, nên cần restart Odoo server để nó hữu hiệu.

Tận hưởng thành quả tại:

  • /foo => trả về "New 'foo' API!"
  • /bar2 => trả về {"content": "New 'bar' API!"}
  • /pet//1 => check log trên console sẽ thấy in ra:
2020-06-17 19:09:25,001 1 WARNING visual_api_dev odoo.addons.mypet_plus.controllers.main: Pet handler called~ 
2020-06-17 19:09:25,005 1 WARNING visual_api_dev odoo.addons.mypet_plus.controllers.main: Post processing~

Như vậy, thừa kế trong module mypet_plus đã thay đổi / chỉnh sửa hành vi của controller trong module mypet. Sau này khi gỡ cài đặt (uninstall) module con, thì hành vi của controller sẽ trở về bản gốc hiện thực trong controller cha.

Thừa kế controller trong Odoo khá đơn giản và dễ thực hiện. Nếu bạn đã nắm rõ cách thức thừa kế trong lập trình ngôn ngữ Python thì sẽ không quá khó khăn để làm quen việc thừa kế class trong Odoo.

Bạn có thể tham khảo thêm tài liệu về controller của Odoo theo đường dẫn bên dưới:

https://www.odoo.com/documentation/13.0/reference/http.html

Download Odoo - Tut 8

Source code download: Tut 8: Inheritance in controllers


minhng.info dự định sẽ mở khóa học training lập trình Odoo OFFLINE ở TP. HCM, nếu bạn nào có nhu cầu giúp mình tham gia khảo sát nhé.

https://forms.gle/K9t2kjx5SCQWftkm8

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é: