Odoo 中的所有功能都带有扩展性,web 功能也不例外,所以已有控制器和模块都能被继承。
作为示例,我们将继承图书目录网页,加入前面添加的图书可用性信息:
- 在控制器端添加对查询参数的支持,访问/library/books?available=1过滤出可借阅图书
- 在模板端,添加一个图书不可用的表示
继承网页控制器
网页控制器不应包含实际业务逻辑,仅集中于展示逻辑。我们可能会需要添加对额外 URL 参数甚至是路由的支持,来改变网页的展示。我们将扩展/library/books来支持available=1参数,以过滤出可借阅图书。
要继承已有控制器,需导入对应对象,然后用方法新增逻辑来进行实现。下面新增ibrary_member/controllers/main.py文件并加入如下代码:
from odoo import http
from odoo.addons.library_app.controllers.main import Books
class BooksExtended(Books):
@http.route()
def list(self, **kwargs):
response = super().list(**kwargs)
if kwargs.get('available'):
Book = http.request.env['library.book']
books = Book.search([('is_available', '=', True)])
response.qcontext['books'] = books
return response
我们要继承的Books控制器在library_app/controllers/main.py中定义。因此需要通过odoo.addons.library_app.controllers.main导入。这和模型不同,模型可以通过 env 对象中的central registry 来引用任意模型类,而无需了解实现它的文件。控制器没有这个,我们需要知道实现需继承控制器的模块和文件。
然后基于Books声明了一个BooksExtended类,类名不具关联性,仅用于继承和扩展原类中定义的方法。
再后我们(重)定义了一个控制器方法 list()。它至少需要一个简单的@http.route()装饰器来保持路径活跃。如果不带参数,将会保留父类中定义的路由。但也可以为@http.route() 装饰器添加参数,来重新定义或替换类路由。
在继承的 list()方法中,一开始使用了 super()来运行已有代码。处理结果返回一个 Response 对象,Response 带有模块要渲染的属性 template,以及渲染使用的上下文qcontext。但还需要生成 HTML,仅会在控制器结束运行时生成。这也让我们可以在最终渲染完成之前可以修改 Response 属性。
list()方法带有**kwargs参数,捕获所有kwargs字典中的参数。这些是 URL 中的参数,如?available=1。方法检测kwargs中available键的值,检测到后改变qcontext来获取仅为可借阅图书的图书记录集。
还要记得让模块知道这个新 Python 文件,需通过将 controllers 子文件夹中添加到library_member/init.py中:
from . import models
from . import controllers
在library_member/controllers/init.py文件中添加一行代码:
from . import main
然后更新模板并访问http://:8069/library/books?available=1 将仅显示勾选了Is Available? 的图书
继承 QWeb 模板
要修改网页的实际展示,就需要继承所使用的 QWeb 模板。我们将继承library_app.book_list_template来展示更多有关不可借阅图书的信息。添加library_member/views/book_list_template.xml文件并加入如下代码:
<odoo>
<template id="book_list_extended"
name="Extended Book List"
inherit_id="library_app.book_list_template">
<xpath expr="//span[@t-field='book.publisher_id']" position="after">
<t t-if="not book.is_available">
<b>(Not Available)</b>
</t>
</xpath>
</template>
</odoo>
网页模板像其它 Odoo 视图类型一样是 XML 文件,同样也可以使用 XPath 来定位元素并对它们进行操作。所继承模型通过在元素中的inherit_id来指明。
然后在 library_member/manifest.py文件中加入该文件的声明:
'data': [
'views/book_view.xml',
'security/library_security.xml',
'security/ir.model.access.csv',
'views/member_view.xml',
'views/library_menu.xml',
'views/book_list_template.xml',
],
更新后访问http://:8069/library/books即可对不可借阅图书展示额外的(Not Available)信息。
演示视频:
http://www.tderp.com/download/details/odoo12-web-864
http://ctdrive.tderp.com/file/13502532-467789777