Odoo起初是一个后台系统,但很快就有了前端界面的需求。早期基于后台界面的门户界面不够灵活并且对移动端不友好。为解决这一问题,Odoo引入了新的网站功能,为系统添加了CMS(ContentManagementSystem)内容管理系统。这使得我们无需集成第三方CMS便可创建美观又高效的前端。本文中我们将学习如何利用Odoo自带的网站功能开发面向前端的插件模块。
本文主要内容有:
1、添加library_website/models/library_member.py文件
2、添加library_website/models/__init__.py文件:
3、添加library_website/__init__.py文件:
4、添加library_website/views/library_member.xml文件:
访问这些网页的都是门户用户,无需访问后台菜单。我们需要为这个用户组设置安全访问权限,否则会在使用图书网站功能时报权限错误。
5、添加library_website/security/ir.model.access.csv文件,添加对图书模型的读权限:
6、在library_website/security/library_security.xml文件中添加记录规则来限制门户用户所能访问的记录:
base.group_portal是门户用户组的标识符。在创建门户用户时,应设置他们的用户类型为Portal,而不是InternalUser。这会让他们属于门户用户组并继承我们上面定义的访问权限:
小贴士:在模型中使用ACL和记录规则来实现安全权限比使用控制器的逻辑要更为安全。这是因为攻击者有可能跳过网页控制器直接使用RPC来访问模型API。
了解了这些,我们就可以开始实现图书网站的功能了。但首先我们来使用简单的HelloWorld网页简短地介绍下基本网站概念。
要开始了解Odoo网页开发的基础,我们将先实现一个HelloWorld网页来展示基本概念和技术。很有想象空间,是不是?
要创建第一个网页,我们需要一个控制器对象。首先来添加controllers/hello.py文件:
1、在library_website/__init__.py文件中添加如下行:
2、在library_website/controllers/__init__.py文件中添加如下行:
3、添加实际的控制器文件library_website/controllers/hello.py,代码如下:
本例中方法执行的处理非常简单,它返回一个带有HTML标记的文本字符串,HelloWorld。
使用Python字符串来创建HTML很快就会觉得乏味。QWeb可用来增添色彩,下面就使用模板来写一个改进版的HelloWorld网页。QWeb模板通过XML数据文件添加,技术层面上它是与表单、列表视图类似的一种视图类型。它们甚至存储在同一个技术模型ir.ui.view中。
然后添加实际的数据文件views/helloworld_template.xml,内容如下:
模板的渲染是通过render()函数的request对象来实现的。
小贴士:注意我们添加了**kwargs方法参数。使用该参数,HTTP请求中的任意附加参数,如GET或POST请求参数,可通过kwargs字典捕获。这会让我们的方法更加健壮,因为即便添加了未预期的参数也不会产生错误。
下面我们来增加点趣味性,创建我们自己的简单CMS。为此我们可以通过URL在路由中使用模板名(一个页面),然后对其进行渲染。然后就可以动态创建网页,通过我们的CMS来提供服务。实现方法很简单:
在werkzeug的行话中,endpoint是路由的别名,由其静态部分(不含占位符)来表示。比如,CMS示例中的endpoint为/hellocms。
大多数情况下,我们要将页面集成到Odoo网站中,因此接下来的示例将使用website插件模块。
前面的示例并未集成到Odoo网站中,并有页面footer和网站菜单。Odoo的website插件模板为方便大家提供这些功能。
要使用网站功能,我们需要在工作实例中安装website插件模块。应当在library_website插件模块中添加这一依赖,修改__manifest__.py的depends内容如下:
要使用网站功能,我们需要对控制器和QWeb模板进行一些修改。控制器中可在路由上添加一个额外的website=True参数:
集成website模块并非严格要求website=True参数,不添加它也可以在模板视图中添加网站布局。但是通过添加可以让我们在网页控制器中使用一些功能:
如果在网页控制器中无需使用上述功能,则可省略website=True参数。但大多数网站QWeb模板需要使用website=True开启一些数据,比如底部公司信息,所以最好还是添加上。
传入QWeb运行上下文语言的网站数据由website/model/ir_ui_view.py文件中的_prepare_qcontext方法设定。
要在模板中添加网站的基本布局,应为QWeb/HTML包裹一个t-call=”website.layout”指令,如下所示:
t-call运行QWeb模板website.layout并向其传递XML内的tcall节点。website.layout设计用于渲染带有菜单、头部和底部的完整网页,交将传入的内容放在对应的主区域内。这样,我们的HelloWorld!示例内容就会显示在Odoo网站页面中了。
我们的网站页面可能需要一些其它的CSS或JavaScript资源。这方面的网页由website管理,因此需要一个方式来告诉它使用这些文件。我们将使用CSS来添加一个简单的删除线效果,创建library_website/static/src/css/library.css文件并添加如下内容:
很快我们就会使用text-strikeout这个新的样式类。当然,可以使用相似的方法来添加JavaScript资源。
既然我们已经过了一遍基础知识,就来一起实现借阅列表吧。我们需要使用/checkoutURL来显示借阅列表的网页。为此我们需要一个控制器方法来准备要展示的数据,以及一个QWeb模板来向用户进行展示。
在模块中添加library_website/controllers/main.py文件,代码如下:
回到我们的代码,它以request.render()方法收尾。和之前一样,我们传入了QWeb模板渲染的标识符,和模板运行用到的上下文字典。本例中我们向模板传入docs变量,该变量包含要渲染借阅记录的记录集。
QWeb模板使用数据文件来添加,我们可以使用library_website/views/checkout_template.xml文件并添加如下代码:
以上代码使用t-foreach指令来迭代docs记录集。我们使用了复选框input并在借阅完成时保持为已选状态。在HTML中,复选框是否被勾选取决于是否有checked属性。为此我们使用了t-att-NAME指定来根据表达式动态渲染checked属性。当表达式运行结果为None(或任意其它false值)时,QWeb会忽略该属性,本例用它就非常方便了。
在渲染任务名时,t-attf指令用于动态创建打开每个指定任务的明细表单的URL。我们使用一个特殊函数slug()来为每条记录生成易于阅读的URL。该链接目前尚无法使用,因为我们还没有创建对应的控制器。
在每条借阅记录上,我们还使用了t-att指令来在借阅为最终状态时应用text-strikeout样式。
借阅列表中的每一项都有一个相应明细页面的链接。我们就为这些链接实现一个控制器,以及实现一个QWeb模板来用于展示。说到这里应该已经很明朗了。
在library_website/controllers/main.py文件中添加如下方法:
注意这里路由使用了带有model(“library.checkout”)转换器的占位符,会映射到方法的doc变量中。它从URL中捕获借阅标识符,可以是简单的ID数值或链接别名,然后转换成相应的浏览记录对象。
对于QWeb模板,应在library_website/views/checkout_template.xml数据文件中添加如下代码:
这里值得一提的是使用了
补充:controllers/__init__.py和__mainfest__.py中请自行添加控制器文件和数据文件的引用
读者现在应该对网站功能的基础有了不错的掌握。我们学习了如何使用网页控制器和QWeb模板来动态渲染网页。然后学习了如何使用website插件并使用它来创建我们自己页面。最后,我们介绍了网站表单插件来帮助我们来创建网页表单。这些都是创建网站功能的核心能技巧。
我们已经学习了Odoo主要构件的开发,是时候学习如何将Odoo服务部署到生产环境了。