odoo13学习15CMS网站开发YongL

Odoo配备了一个功能齐全的内容管理系统(CMS)。通过拖放功能,你的最终用户可以在几分钟内设计一个页面,但是在OdooCMS系统中开发一个新功能或构建块就不那么简单了。本章将逐步指导你在OdooCMS系统中开发功能。

管理静态资源

现代网站包含很多JavaScript和CSS文件。在浏览器中加载页面时,这些静态文件向服务器发出单独的请求。请求越多,网站速度越慢。为了避免这个问题,大多数网站通过合并多个文件来提供静态资源。市场上有一些工具可以管理这类事情,但Odoo有自己的实现来管理静态资源。

Odoo中的资源包和不同资产是什么

在Odoo中,静态资源管理不像在其他应用程序中那样简单。Odoo有很多不同的应用程序和代码库。不同的Odoo应用程序有不同的用途和用户界面。这些应用程序不共享共同的代码,因此在某些情况下,我们希望加载一些资源,但不是全部。在页面中加载不必要的静态资源不是一个好的做法。为了避免在所有应用程序中加载额外的资源,Odoo对不同的代码库使用不同的资源包。

这里是不同的资源捆绑使用的Odoo:

还有其他一些用于特定应用程序的资源包:point_of_sale.assets,survey.survey_assets,mass_mailing.layout,和website_slides.slide_embed_assets.

Odoo通过AssetsBundle类管理它的静态资源,它位于/odoo/addons/base/models/assetsbundle.py。资源包不仅组合了多个文件;它还包含了更多的特性。这里是它提供的功能列表:

自定义资源

正如我们所看到的,Odoo对于不同的代码库有不同的资源。为了得到正确的结果,您需要选择正确的资源包,将定制的JavaScript和CSS文件放在其中。例如,如果你正在设计一个网站,你需要把你的文件放在web.assets_frontend。在下一个内容中,您将看到如何在现有的资产包中包含定制的CSS/JavaScript。尽管这种情况很少见,但有时您需要创建一个全新的资产包。您可以创建自己的资源包,正如我们将在下一节中描述的那样。

怎么做呢

按照以下步骤创建一个自定义资源包:

1.创建QWeb模板,并添加您的JavaScript,CSS,或SCSS文件,如下:

......

它是如何工作的…

在步骤1中,我们使用外部IDmy_custom_assets创建了新的QWeb模板。在这个模板中,您需要列出所有的CSS、SCSS和JavaScript文件。首先,Odoo将编译SCSS文件到CSS,然后,Odoo将结合所有的CSS和JavaScript文件到一个单独的CSS和JavaScript文件。

在步骤2中,我们已经在模板中加载了CSS和JavaScript资产。t-css和t-js属性仅用于加载样式表或脚本。

在大多数网站开发中,您需要在现有的资源包中添加JavaScript和CSS文件。添加一个新的资源包是非常罕见的。只有当你想开发没有OdooCMS功能的页面/应用程序时才需要。在下一个章节中,您将了解如何在现有的资源包中添加自定义CSS/JavaScript。

有更多的…

如果您正在使用Odoo中的资源,以下是您需要知道的一些事情

在Odoo中调试JavaScript非常困难,因为AssetBundle会将多个JavaScript文件合并到一个文件中,并且还会缩小它们。

调试JavaScript可能是非常困难的Odoo,因为AssetBundle合并多个JavaScript文件到一个单一的,也缩小了他们。通过使用启用带资源的developer模式,您可以跳过资源绑定,并且页面将分别加载静态资源,以便您可以轻松地进行调试。

合并后的资产只生成一次,并存储在ir.attachment模型中。之后,它将从附件中提供。如果您想重新生成资源,您可以从调试选项中进行,如下面的截图所示:

如您所知,Odoo将只生成一次资源。这种行为在开发过程中可能会令人头疼,因为它需要频繁地重新启动服务器。要克服这个问题,可以在命令行中使用dev=xml,它将直接加载资源,因此不需要重新启动服务器。

扩展CSS和JavaScript的网站

在这个章节中,我们将介绍如何添加自定义样式表和JavaScript到网站。

准备

我们将使用第4章中的my_library模块,创建Odoo附加模块。我们将添加CSS,SCSS和JavaScript文件,这些文件将修改网站。由于我们正在修改网站,我们将需要添加网站的依赖性。像这样修改清单:

...'depends':['base','website'],...怎么做呢

覆盖主网站模板,注入你的代码,如下:

1.添加一个名为views/templates.xml的文件,并添加一个空视图覆盖,如下所示(不要忘记在__manifest__.py中列出该文件):

2.添加CSS和SCSS文件的引用,如下:

4.添加一些CSS代码到static/src/CSS/my_library.css,如下:

bodymain{background:#b9ced8;}5.向static/src/SCSSmy_library.scss添加一些SCSS代码。scss,如下所示:

$my-bg-color:#1C2529;$my-text-color:#D3F4FF;nav.navbar{background-color:$my-bg-color!important;.navbar-nav.nav-linkspan{color:darken($my-text-color,15);font-weight:600;}}footer.o_footer{background-color:$my-bg-color!important;color:$my-text-color;}6.添加一些JavaScript代码到static/src/js/my_library.js如下:

odoo.define('my_library',function(require){varcore=require('web.core');alert(core._t('Helloworld'));return{//ifyoucreatedfunctionalitytoexport,addithere}});更新你的模块后,你应该看到Odoo网站有自定义的颜色在菜单,正文,和页脚,和一个有点恼人的Helloworld弹出在每个页面加载,如下截图所示:

在第4步中,我们添加了CSS,用于设置网站的主体背景颜色。

对于CSS/SCSS文件,有时候,顺序很重要。因此,如果您需要覆盖在另一个附加组件中定义的样式,您必须注意您的文件是在您想要修改的原始文件之后加载的。

这可以通过调整视图的优先级字段或直接继承加载项的视图来实现,该视图将引用注入CSS文件。有关详细信息,请参阅第10章后端视图中的更改现有视图-视图继承配方。

对于第二个参数,定义函数只接收一个参数require,您可以使用该函数获取对其他模块或核心中定义的JavaScript名称空间的引用。使用这个与Odoo的所有交互,永远不要依赖于全局Odoo对象。

然后,您自己的函数可以返回一个对象,该对象指向您希望为其他附加组件提供的引用,或者如果没有这样的引用,则不返回任何引用。如果你已经从你的函数返回了一些引用,你可以在另一个函数中使用它们,如下面的例子所示:

odoo.define('my_module',function(require){vartest={key1:'value1',key2:'value2'};varsquare=function(number){return2*2;};return{test:test,square:square}});//Inanotherfileodoo.define('another_module',function(require){varmy_module=require('my_module');console.log(my_module.test.key1);console.log('squareof5is',my_module.square(5));});介绍了Odoo9.0的要求机制。在旧版本中,处理JavaScript的外接程序需要在openerp命名空间中定义与外接程序同名的函数。此函数接收到当前加载实例的引用作为参数,从该参数访问API函数。因此,为了升级现有代码,将其更改为odoo.define子句,并通过require导入必要的对象。

创建或修改模板-QWeb

我们需要定义以下几个控制器和视图:

1.在views/templates.xml中添加一个最小模板,如下所示:

2.在website.layout中,使用oe_structure类添加droppable元素,如下所示:

Editabletextandsupportsdraganddrop.

3.将代码块附加到网站中。显示图书信息的版面如下:

Authors

4.添加一个不可编辑的元素到website.layout,如下所示:

Thisisanon-editabletextafterthelistofbooks.

5.在controllers/main.py中添加一个提供图书列表的控制器,如下所示:

首先,我们创建了一个名为books的模板,用于生成显示图书列表所需的HTML。所有代码都包装在带有t-call属性集的t元素中,这使得Odoo使用website.layout模板呈现页面,并将我们的内容插入到模板中。website.layout包括所有必需的实用程序,比如Bootstrap、jQuery、FontAwesome等等。这些实用程序用于设计web页面。默认情况下,它包括所有必要的资产,如Bootstrap、jQuery、FontAwesome等等。website.layout还包括默认的页眉、页脚、代码片段和页面编辑功能。这样,我们就得到了一个完整的Odooweb页面,包括菜单、页脚和页面编辑功能,而不必在所有页面中重复这些代码。如果你不使用t-call="website_layout",你将不会得到默认的页眉、页脚和网站编辑功能。

在website.layout中,我们添加了带有QWeb模板属性的HTML来显示图书列表。现在,我们将查看不同的QWeb属性及其用法。在此模板中,您将能够访问从main.py中控制器传递的参数。

Loop

为了处理记录集或可迭代数据类型,您需要一个结构来遍历列表。在QWeb模板中,这可以通过t-foreach元素完成。迭代可以发生在t元素中,在这种情况下,它的内容会对t-foreach属性中传递的iterable的每个成员重复,如下所示:

这将以如下方式呈现:

1

2

3

4

5

还可以将t-foreach和t-as属性放置在任意元素中,此时该元素及其内容将针对迭代中的每个项重复。看看下面的代码块。这将产生与前面例子完全相同的结果:

在我们的示例中,看一下t-call元素的内部,这里发生了实际的内容生成。模板期望使用具有名为booksset变量的上下文进行呈现,该变量在t-foreach元素中遍历该模板。t-as属性是强制性的,它将用作迭代器变量的名称,用于访问迭代数据。虽然这种构造最常见的用途是遍历记录集,但您可以在任何可迭代的Python对象上使用它。

在t-foreach循环中,您可以访问两个额外的变量,它们的名称派生于附带的t-as属性。正如前面示例中的book一样,我们可以访问book_odd变量,该变量在迭代时包含奇数索引的值为真,偶数索引的值为假。在这个例子中,我们使用这个可以在纸牌中交替使用背景颜色。

以下是其他可用的变量:

book_index,它返回迭代中的当前(从零开始)索引。

book_first和book_last:如果这是第一次或最后一次迭代,则book_first和book_last分别为真。

book_value,如果我们遍历的book变量是一个字典,它将包含条目的值;在本例中,book将遍历字典的键。

book_size,它是集合的大小(如果可用)。

book_even和book_odd根据迭代索引获得真值。

book_parity:迭代时包含偶数索引的偶数值,以及奇数索引的奇数值。

给出的例子是基于我们的例子。在您的例子中,需要用t-as属性处的值替换book。

QWebtemplate可以动态设置属性值。这可以通过以下三种方式来实现。

第一种方法是通过t-att-$attr_name。在模板呈现时,创建一个属性$attr_name;它的值可以是任何有效的Python表达式。这用当前上下文计算,结果设置为属性的值,如下所示:

它将被渲染成这样:

第二种方法是通过t-attf-$attr_name。这与前面的选项相同。唯一的区别是只有字符串在{{..}}和#{…}之间时才求值。当值与字符串混合时,这很有帮助。它主要用于求值类,如这个例子:

Simplebootstrapalert它将被渲染成这样:

SimplebootstrapalertSimplebootstrapalertSimplebootstrapalert第三种方法是通过t-att=mapping选项。在呈现字典数据的模板被转换为属性和值之后,此选项接受字典。看看下面的例子:

该模板呈现后,将被转换为以下内容:

在我们的示例中,我们使用t-attf-class来获得基于索引值的动态背景。

Fields

h3和div标记使用t字段属性。t-field属性的值必须用于长度为1的记录集,这允许用户在编辑模式下打开网站时更改web页面的内容。当您保存页面时,更新后的值将存储在数据库中。当然,这要经过权限检查,并且只有当前用户对显示的记录具有写权限时才允许。通过一个可选的t-options属性,您可以提供一个要传递给字段呈现器的dictionary选项,包括要使用的小部件。目前,后台并没有大量的小部件,所以这里的选择有点有限。例如,如果你想从二进制字段显示一个图像,那么你可以使用像这样的图像小部件:

t-field有一些局限性。它只对记录集有效,对元素无效。为此,需要使用一些HTML元素,如

。t字段属性还有一个可选属性,即t-esc。t-esc属性不限于记录集;它也可以用于任何数据类型,但不能在网站中编辑。

t-esc和t-field之间的另一个区别是,t-field显示基于用户语言的值,而t-esc显示来自数据库的原始值。例如,对于在首选项中配置了英语语言并将datetime字段设置为与t字段一起使用的用户,结果将以12/15/201817:12:13格式呈现。相反,如果使用t-esc属性,则结果将呈现如下格式:2018-12-1516:12:13。

Conditionals

注意,显示发布日期的部分由带有t-if属性集的t元素包装。该属性作为Python代码计算,只有当结果是真实值时才呈现元素。在下面的示例中,我们只显示div类,如果确实设置了发布日期。但是,在复杂情况下,您可以使用t-elif和t-else,如下面的示例所示:

Textwillbeaddedofstateisnew.

Textwillbeaddedofstateisprogress.Textwillbeaddedforallotherstages.Settingvariables

QWeb模板还能够在模板本身中定义变量。定义模板之后,您可以在后续模板中使用该变量。你可以这样设置变量:

Subtemplates(子模板)

如果您正在开发一个大型应用程序,管理大型模板可能会很困难。QWeb模板支持子模板,因此您可以将大型模板划分为较小的子模板,并且可以在多个模板中重用它们。对于子模板,你可以使用一个t-call属性,就像这个例子:

TestTemplate

Inlineediting(内联编辑)

用户可以在编辑模式下直接从网站修改记录。t字段节点加载的数据在默认情况下是可编辑的。如果用户更改了这样一个节点中的值并保存了页面,那么这些值也将在后端进行更新。别担心;为了更新记录,用户需要对记录进行写权限。注意,t字段只对记录集有效。要显示其他类型的数据,可以使用t-esc。它的工作原理与t-field完全相同,但唯一的区别是t-esc是不可编辑的,可以用于任何类型的数据。

注意,通过网站编辑器编辑视图会在此视图上设置noupdate标志。这意味着后续的代码更改将永远不会进入客户的数据库。为了更方便地使用内联编辑并在后续版本中更新HTML代码,创建一个包含语义HTML元素的视图和第二个注入可编辑元素的视图。然后,只有后一个视图是noupdate,您仍然可以更改前一个视图。

对于这里使用的其他CSS类,请参考Bootstrap文档,链接见本节的“参见”部分。

在函数结束时,我们通过呈现模板返回结果;然后传递模板中使用的所有图书的记录集。有关更新现有路由的更多信息,请参考第14章“Web服务器开发”中的修改现有处理程序内容。

要修改现有模板,可以在模板上使用inherit_id属性,然后使用xpath元素,比如视图继承。例如,我们希望通过继承books模板来显示authors标签附近的作者数量。

我们可以通过以下方式做到这一点:

Authors()继承的工作原理与视图完全相同,因为在内部,QWeb模板是QWeb类型的普通视图。template元素是记录元素的简写,它为您在记录上设置一些属性。虽然没有理由不使用template元素的便利,但是您应该知道在幕后发生了什么:元素创建了一个具有qweb类型的ir.ui.view模型的记录。然后,根据模板元素的名称和inherit_id属性,将设置视图记录上的inherit_id字段。

另请参阅

要有效设计QWeb模板,请参考以下几点:

有关视图继承的详细信息,请参阅第10章后端视图中的更改现有视图-视图继承。

关于控制器的更深入的讨论,请参考第14章“web服务器开发”中的“从网络创建一个可访问的路径并限制对web可访问路径的访问”。

管理动态路由

在网站开发项目中,经常需要创建带有动态url的页面。例如,在电子商务中,每个产品都有一个带有不同URL的详细页面。在这个章节中,我们将创建一个web页面来显示图书的详细信息。

我们将使用上一个节中的my_library模块。为了使图书细节页面更吸引人,我们需要添加一些新字段。请在library.book模型中添加以下两个新字段并形成视图,如下所示:

classLibraryBook(models.Model):_name='library.book'name=fields.Char('Title',required=True)date_release=fields.Date('ReleaseDate')author_ids=fields.Many2many('res.partner',string='Authors')image=fields.Binary(attachment=True)html_description=fields.Html()怎么做呢

按照以下步骤生成书籍的详细信息页面:

1.在main.py中为图书详细信息添加一个新路由,如下所示:

Authors

3.在booklist模板中添加一个按钮,如下所示。此按钮将重定向到图书详情网页:

在第一步中,我们为图书详细信息页面创建了一个动态路径。在这个路径中,我们添加了。它接受带有整数的url,比如/books/1。Odoo认为这个整数是数据库的ID。当这个URL被访问时,Odoo获取一个记录集并将它作为参数传递给函数。因此,当从浏览器访问/books/1时,函数library_book_detail()中的book参数将拥有该库的一个记录集。ID为1的图书模型。我们传递了这个图书记录集,并呈现了一个名为my_library.book_detail的新模板。

在第二步中,我们创建了一个名为book_detail的新QWeb模板来呈现图书详细信息页面。这很简单,是使用引导结构创建的。如果您选中,我们已经在详细页面中添加了html_description。字段html_description有一个HTML类型的字段,因此您可以在字段中存储HTML数据。Odoo自动添加代码片段拖放支持的HTML类型的字段。所以,现在我们可以在bookdetails页面中使用片段了。HTML字段中的代码片段存储在一本书的记录中,因此您可以为不同的图书设计不同的内容。

在最后一步中,我们添加了一个带有锚标记的链接,这样访问者就可以被重定向到图书详细信息页面。

Odoo使用werkzeug处理HTTP请求。Odoo在werkzeug周围增加了一个薄薄的包装纸,方便处理路线。您在最后一个示例中看到了路由。这是Odoo自己的实现,但是它也支持所有来自werkzeug路由的特性。因此,你可以这样使用路由:

/page/接受整型值

/page/接受选择的值

/pages/接受字符串

/pages//接受多个值

向用户提供代码片段

网站设计者在网站编辑模式中提供构建块,它可以在页面上。本节将介绍如何在内部提供自己的块(称为片段)。

对于这个章节,我们将使用上一个章节中的my_library模块。

一个代码片段实际上就是一个注入到插入块栏中的qwebview,它是由QWebview本身定义的。遵循以下步骤:

1.添加名为views/snippets.xml的文件,如下所示:

2.为代码片段添加一个模板,如下所示:

Latestbooks

NameReleasedate3.继承代码片段模板并附加代码片段和选项,如下所示:

4.在继承的代码片段模板中添加代码片段选项,如下所示:

odoo.define('my_library.snippets',function(require){"usestrict";varrpc=require('web.rpc');varAnimation=require('website.content.snippets.animation');varoptions=require('web_editor.snippets.options');//AddsnippetoptionandanimationJavaScripthere});6.添加如下选项来决定我们想要在代码片段中显示多少本书:

options.registry.book_count=options.Class.extend({selectCount:function(previewMode,value,$opt){vartable=this.$target.find('table');varoldClass=table.attr('class');varnewTable=$('

NameReleasedate
');newTable.attr('class',oldClass);newTable.attr('data-rows',value);table.replaceWith(newTable);this._refreshAnimations();}});7.添加动画来获取图书数据并显示在页面中,如下图所示:

Animation.registry.book_snippet=Animation.Class.extend({selector:'.book_snippet',start:function(){varself=this;varrows=this.$el.data().rows||5;this.$el.find('td').parents('tr').remove();rpc.query({model:'library.book',method:'search_read',domain:[],fields:['name','date_release'],orderBy:[{name:'date_release',asc:false}],limit:rows,}).then(function(data){_.each(data,function(book){self.$el.append($('').append($('').text(book.name),$('').text(book.date_release)));});});},});在更新模块之后,将向您提供一个名为Latestbooks的新代码片段,其中有一个选项可以更改最近添加的图书数量。我们还添加了更改表设计的选项,可以在单击表时显示。

在第一步中,我们添加了一个新的XML文件snipptes.xml,并在资源中添加了一个JS文件。代码片段只是没有website.layout的QWeb模板。

在第二步中,我们为该书创建了book_snippet模板。一般来说,使用section元素和引导类是一个好主意,因为对于它们,Odoo的编辑器提供了编辑、背景和调整大小的控制。在代码片段主体中,我们刚刚添加了标题和带有标题的表。我们想把最新的书陈列在我们的箱子里。最新的图书列表不是固定的,每次新书出版时,该列表都会更改。因此,我们希望动态地将图书详细信息插入到表中。在接下来的几个步骤中,我们将添加JavaScript来获取最新书籍列表并将它们添加到表中。

在第三步中,我们继承了website.snippet模板来添加代码片段及其选项。第一个xpath将book_snippet添加到featuresnippet部分。要添加代码片段,需要使用t-snippet属性。您还需要添加t-thumbnail属性,它将是代码片段的缩略图的URL。使用position属性确定将在哪个部分显示代码片段。我们的选择是//div[@id='snippet_feature']/div[@class='o_panel_body'],这将它放在features部分中。使用snippet_structure、snippet_content和snippet_effect的id,您可以将代码片段放在其他相应的部分中。

在第二个xpath中,我们为代码片段添加了选项。通过步骤4在这个xpath中添加了两个选项。第一个选项用于选择要在表中显示的图书数量。代码片段选项有各种类型。在本例中,我们使用了data-js="book_count"的自定义选项。当使用data-js选项时,需要在options_registry中使用属性的值注册它。当用户更改选项时,它将调用已注册选项中的函数,然后您需要在元素上设置选项值。当页面被重新加载时,渲染函数(Odoo动画框架)会使用这些值。

您可以在步骤6中检查这一点,其中我们添加了选项,如options.registry.book_count。在函数体中,我们在this.$target中获得一个代码片段元素,函数体中的其余内容是用基本的JQuery语法编写的。

我们还在步骤4中添加了一个代码片段选项,用于更改表样式。对于这个选项,我们使用了data-toggle-class属性。当用户点击属性data-toggle-class的选项时,Odoo将切换属性值中给出的类。这种类型的选项不需要JavaScript代码。在Odoo中还有一种称为data-select-class的选项,它一次只支持一个类。我们在示例中没有使用这个,但您可以测试它。

如果您注意到,data-selector属性包含一个JQuery选择器,用于确定要显示选项的哪个元素。在本例中,第一个选项列表是在整个容器被选中时显示的,而第二个选项列表是在表被选中时显示的。

在步骤6和步骤7中,我们在Animation.registry中添加了book_snippet,它将从数据库中获取图书数据,并在snippet主体中追加表行。它使用代码片段动画框架在每次加载代码片段时执行代码。我们使用它来查询要呈现给用户的当前图书列表。这里的关键属性是已定义的选择器,它指示框架在有匹配选择器的元素时运行我们的类。在内部,我们使用data-rows选项,它是从options.registry.book.count添加的,用于确定需要显示多少行。

我们的章节中给出的示例用于创建动态片段。如果您不需要动态代码片段,而只想添加静态内容,那么您可以直接在代码片段中添加所有内容。不需要为静态片段添加JavaScript。

在前面的示例中,我们创建了一个动态代码片段。如果您不需要动态代码片段,而只想添加静态内容,那么您可以直接在代码片段中添加所有内容。在这种情况下,将不需要额外的JavaScript。

在这种情况下,将不需要额外的JavaScript。Odoo的编辑器提供了很多现成的选项和控制,对于静态代码片段来说,它们已经足够了。

你可以在website/views/snippets.xml找到所有现有的片段和选项。Snippet选项还支持data-exclude、data-drop-near和data-drop-in属性,这些属性决定在将Snippet拖出Snippet栏时可以将其放置在何处。这些也是JQuery选择器,在本节的第3步中,我们没有使用它们,因为我们允许将代码片段放到内容可以放到的任何地方。

从用户那里获取输入

对于这个章节,我们将使用上一个章节中的my_library模块。我们将需要一个新的模型来存储用户提交的问题。因此,在开始此内容之前,请修改前面的代码。在库中添加一个字段。图书模型和新书。问题模型,如下:

classLibraryBook(models.Model):_name='library.book'name=fields.Char('Title',required=True)date_release=fields.Date('ReleaseDate')author_ids=fields.Many2many('res.partner',string='Authors')image=fields.Binary(attachment=True)html_description=fields.Html()book_issue_id=fields.One2many('book.issue','book_id')classLibraryBookIssues(models.Model):_name='book.issue'book_id=fields.Many2one('library.book',required=True)submitted_by=fields.Many2one('res.users')isuue_description=fields.Text()在book表单视图中添加一个book_issues_id字段,如下所示:

......在ir.model.access.csv文件中为新book.issue模型添加访问权限,如下:

acl_book_issues,library.book_issue,model_book_issue,group_librarian,1,1,1,1我们已经为图书问题添加了一个新模型,现在,我们将添加一个带有HTML表单的新模板。

按照以下步骤为问题页面创建一个新的路由和模板页面:

1.在main_py中添加一个新路由,如下所示:

Booksubmittedsuccessfully

Reporttheanotherbookissue

Reportthebookissue

Submit3.为页面添加条件标题,如下所示:(第2步中的粗体)

Booksubmittedsuccessfully

Reporttheanotherbookissue

Reportthebookissue

4.添加
提交问题如下:(第2步粗体)

Submit更新模块并打开/books/submit_issuesURL。从这个页面,您可以提交这本书的问题。提交后,您可以在后台将它们签入相应的图书表单视图。

在此章节的第1步中,我们创建了一个提交图书问题的路径。函数中的**post参数将接受URL中的所有查询参数。您还将在**post参数中获得提交的表单数据。在我们的示例中,我们使用了相同的控制器来显示页面并提交问题。如果我们发现数据后,我们将创建一个新的问题book.issue模型,然后将用户重定向到问题页面提交的查询参数,所以用户可以看到提交承认问题,因此可以提交另一个问题,如果他/她想要的。

注意,我们使用sudo()来创建一个图书发行记录,因为普通用户(访问者)没有创建新的图书发行记录的访问权限。尽管如果用户从web页面提交了一个问题,仍然需要创建图书发行记录。这是使用sudo()的一个实际示例。

在步骤2中,我们已经为问题页面创建了模板。

在步骤3中,我们添加了条件标题。成功标头将在提交问题后显示。

在步骤4中,我们添加了带有三个字段的

:csrf_token、图书选择和问题描述。最后两个字段用于获取网站用户的输入。但是,csrf_token用于避免跨站点请求伪造(CSRF)攻击。如果不在表单中使用它,用户将无法提交表单。当您提交表单时,您将在第1步的books_issues()方法中获得作为**post参数的提交数据。

在某些情况下,如果您想禁用csrf验证,您可以在路由中使用csrf=False,如下所示:

如果你想,你可以使用单独的路由页面和post数据,你可以在表单中添加操作如下:

......此外,您可以通过在路由中添加方法参数来限制get请求,如下所示:

Odoo为模板(页面)提供内置的SEO支持。然而,有些模板在多个url中使用。例如,在在线商店中,产品页面使用相同的模板和不同的产品数据呈现。对于这类情况,我们希望每个URL都有单独的SEO选项。

对于这个章节,我们将使用上一个章节中的my_library模块。我们将为每个图书详细信息页面存储单独的SEO数据。在开发此章节之前,您应该在不同的图书页面中测试SEO选项。你可以从顶部的“提升”下拉菜单中得到一个SEO对话框,如下图所示:

如果您在不同的图书详细信息页面中测试SEO选项,您将注意到更改一个图书页面中的SEO数据将反映在所有图书页面上。我们将在这个章节中解决这个问题。

为每本书管理单独的SEO选项,遵循以下步骤:

1.在library_book模型中继承SEO元数据mixin,如下所示:

classLibraryBook(models.Model):_name='library.book'_description='LibraryBook'_inherit=['website.seo.metadata']name=fields.Char('Title',required=True)date_release=fields.Date('ReleaseDate')author_ids=fields.Many2many('res.partner',string='Authors')image=fields.Binary(attachment=True)html_description=fields.Html()book_issue_ids=fields.One2many('book.issue','book_id')def_default_website_meta(self):res=super(LibraryBook,self)._default_website_meta()res['default_opengraph']['og:image']=self.env['website'].image_url(self,'image')res['default_twitter']['twitter:image']=self.env['website'].image_url(self,'image')returnres2.在图书详细信息路由中以main_object的形式传递图书对象,如下所示:

要在模型的每个记录上启用SEO,您需要在模型中继承website.seo.metadata。这将在library.book模型中添加一些字段和方法。网站将使用这些字段和方法为每本书存储单独的数据。

如果你想看到SEOmixin的字段和方法,在/addons/website/models/website.py文件中搜索website.seo.metadata模型。

Odoov12增加了对开放Graph和Twitter共享的元标签的支持。如果您想在页面中添加您的自定义meta标签,您可以在添加SEOmixin之后覆盖_default_website_meta()。

一个网站的网站地图对任何一个网站都是至关重要的。搜索引擎将使用网站网站地图来索引网站的页面。在这个章节中,我们将在网站地图中添加图书详细信息页面。

准备……

对于这个章节,我们将使用上一个章节中的my_library模块。如果你想在Odoo中检查当前的站点地图,请在浏览器中打开/sitemap_xml。这将没有书的URL。

按照以下步骤将图书页面添加到sitemap.xml:

1.导入main.py中给定的方法,如下所示:

在第一步中,我们导入了一些必需的函数。slug用于根据一个记录名称生成一个干净的、用户友好的URL。sitemap_qs2dom用于根据路由和查询字符串生成域。

在第2步中,我们创建了一个Python生成器函数sitemap_books()。每当生成站点地图时,都会调用此函数。在调用期间,它将接收三个参数——envOdoo环境、rule路由规则和qs查询字符串。在函数中,我们已经用sitemap_qs2dom生成了一个域。然后,使用生成的域搜索图书记录,通过slug()方法生成位置。使用slug,您将获得一个用户友好的URL,如/books/oddoo-12-development-cookbook-1,而不是books/1。

在第3步中,我们将sitemap_books()函数引用传递给带有关键字站点地图的路由。

OdooCMS内置了对GeoIP的支持。在实时环境中,您可以基于IP跟踪访问者的国家。在这个章节中,我们将根据访问者的IP地址获得访问者的国家。

对于这个章节,我们将使用上一个章节中的my_library模块。在这个章节中,我们将根据访问者的国家在网页中隐藏一些书籍。您需要下载GeoIP数据库。之后,您需要从cli选项中传递数据库位置,如下所示:

./odoo-bin-cconfig_file--geoip-db=location_of_geoip_DB1.在library.book模型中添加restrict_country_idsm2m字段,如下所示:

classLibraryBook(models.Model):_name='library.book'_description='LibraryBook'_inherit=['website.seo.metadata']name=fields.Char('Title',required=True)date_release=fields.Date('ReleaseDate')author_ids=fields.Many2many('res.partner',string='Authors')image=fields.Binary(attachment=True)html_description=fields.Html()book_issue_ids=fields.One2many('book.issue','book_id')restrict_country_ids=fields.Many2many('res.country')......2.在library.books模型的表单视图中添加一个restrict_country_ids字段,如下所示:

......3.更新/books控制器以根据国家限制图书,如下所示:

警告:此章节不适用于本地服务器。它将需要一个托管服务器,因为在本地机器中,您将获得本地IP,这与任何国家都没有关系。

您还需要正确配置nginx。

在第一步中,我们在library.book模型中添加了一个新的restricted_country_idsmany2many类型字段。如果网站访问者来自受限国家,我们将把书藏起来。

在步骤2中,我们刚刚在图书的表单视图中添加了一个restricted_country_ids字段。如果GeoIP和NGINX配置正确,Odoo会在request.session.geoip添加GeoIP信息,然后你可以从中获得国家代码。

在第三步中,我们从GeoIP获取了国家代码,然后根据country_code获取了国家的记录集。在获得访问者的国家信息后,我们根据受限制的国家使用域名过滤图书。

如果你没有真正的服务器,你想要测试它,你可以在控制器中添加一个默认的国家代码,像这样:country_code=request.session.geoip和request.session.geoip.get('country_code')或'IN'

对于这个章节,我们将使用上一个章节中的my_library模块。Odoo内置了对UTMs的支持。对于我们的库应用程序,我们没有任何使用UTMs的实际案例。但是,在这个章节中,我们将在my_library中的/books/submit_issues生成的问题中添加UTM。

按照以下步骤链接由/books/submit_issuesURL上的web页面生成的图书问题中的UTMs:

1.在manifest.py的depends部分添加一个utm模块,如下:

'depends':['base','website','utm'],2.在书中继承utm.mixin。发行模式如下:

classLibraryBookIssues(models.Model):_name='book.issue'_inherit=['utm.mixin']book_id=fields.Many2one('library.book',required=True)submitted_by=fields.Many2one('res.users')issue_description=fields.Text()3.在book_issue_ids字段的树形视图中添加一个campaign_id字段,如下所示:

......更新模块以应用更改。要测试UTM,您需要执行以下步骤:

在第一步中,我们在book.issue模型中继承了utm.mixin。这将向book.issue模型添加以下字段:

campaign_id:utm.campaign模型中的Many2one字段。这是用来跟踪不同的活动,如夏季和圣诞节特辑。

如果访问者从任何营销媒体访问您的网站,那么当在网站页面上创建记录时,campaign_id、source_id和medium_id字段将自动填充。

在我们的示例中,我们只跟踪了campaign_id,但是还可以添加source_id和medium_id。

在v12中,Odoo增加了对多个网站的支持。这意味着同一个Odoo实例可以在多个域上运行,也可以在显示不同记录时运行。

对于这个章节,我们将使用上一个章节中的my_library模块。在这个章节中,我们将会隐藏基于网站的书籍。

按照以下步骤,使网上网站-多网站兼容:

1.在library.book模型中添加website.multi.mixin,如下所示:

classLibraryBook(models.Model):_name='library.book'_inherit=['website.seo.metadata','website.multi.mixin']...2.在图书表单视图中添加website_id,如下所示:

......3.修改/books控制器中的域,如下所示:

您还可以尝试直接从URL(如/books/1)访问图书详细信息。如果一本书不是来自该网站,它将显示为404。

在第一步中,我们添加了website.multi.mixin。这个mixin添加了一个基本实用程序来处理模型中的多个网站。这个mixin在模型中添加website_id字段。该字段用于确定记录用于哪个网站。

在第2步中,我们在图书的表单视图中添加了website_id字段,因此图书将根据网站进行过滤。

在步骤3中,我们修改了用于查找图书列表的域。request.website.website_domain()将返回一个域,该域将过滤掉不来自该网站的图书。

请注意,有些记录没有设置任何website_id。这些记录将在所有网站上显示。这意味着,如果某本书没有website_id字段,那么该图书将显示在所有网站上。

然后,我们在web搜索中添加域名,如下:

在步骤4中,我们限制了图书访问。如果这本书不是为当前的网站,那么我们将提出一个未发现的错误。can_access_from_current_website()方法将返回值True,如果图书记录用于当前活动的网站,则返回值为True;如果图书记录用于另一个网站,则返回值为False。

如果勾选,我们已经在两个控制器中添加了**post。这是因为没有它,**post/books和/books/;将不接受查询参数。当从网站切换器切换网站时,它也会产生一个错误,所以我们添加了它。通常,在每个控制器中添加**post是一个很好的实践,这样它就可以处理查询参数。

THE END
1.品牌营销策划方案模板,照着做准没错!标题:品牌营销策划方案模板,照着做准没错! 在竞争激烈的市场环境中,品牌营销策划成为企业提升知名度、拓展市场份额的重要手段。一份优秀的品牌营销策划方案,不仅能够帮助企业明确目标,还能有效提升品牌形象。下面,我们就来为大家介绍一份品牌营销策划方案模板,照着做,准没错! http://news.xnnews.com.cn/taoyitui/Article-xiaoxiaoYi-2602.html
2.产品详情页设计全攻略:打造吸引眼球的销售利器品牌视觉元素:品牌视觉元素是塑造品牌形象的重要组成部分。通过运用统一的色彩、字体、图标等视觉元素,能够营造出独特的品牌氛围和视觉风格。在设计产品详情页时,应注重品牌视觉元素的运用和统一,确保页面风格与品牌形象相协调。 品牌口碑:品牌口碑是提升品牌认知度的重要因素之一。通过展示用户评价、媒体报道等口碑信息,能https://pbids.com/aboutUs/pbidsNews/1861306466356531200
3.如何制作满足电商销售需求的促销活动页面?制作满足电商销售需求的促销活动页面需要考虑多个因素,包括页面设计、内容编写、用户体验等。以下是一个适用于大多数电商平台的制作步骤,帮助您制作一个成功的促销活动页面。第一步:设定目标在开始设计促销活动页面之前,您需要明确促销活动的目标。是为了提高销售量,吸引新客户,还是推动回头客户购买更多产品?设定明确https://baijiahao.baidu.com/s?id=1809432988221098628&wfr=spider&for=pc
4.网页模板,网站模板免费下载,做网站首选模板无忧模板无忧是国内最具人气的网站模板、网页模板下载站,提供网站模板、网页模板、程序模板下载及建站相关素材、教程资源。众多专业模板设计师,新模板每日更新http://www.mb5u.com/
5.百度推广营销页怎么做的,百度推广营销页怎么做模板百度推广营销页怎么做模板 制作百度推广营销页的模板需要考虑以下几个要素: 1. 页面布局:设计简洁、清晰的布局,在页面上方使用大标题吸引用户注意力,将重要信息放在页面的核心位置。 2. 目标明确:明确页面的目标,即想要用户做出怎样的行动,如填写表单、购买产品等,然后通过设计和文字引导用户完成目标。 https://qyyi.cn/news/show-330163.html
6.网站上关键词的推广怎么做/营销型网站的推广方法网站上关键词的推广怎么做,营销型网站的推广方法,营销型网站怎么收费,做优化网站是什么意思1 部署Zabbix监控平台1.1 问题本案例要求部署一台Zabbix监控服务器,一台被监控主机,为进一步执行具体的监控任务做准备:在监控服务器上安装LAMP环境修改PHP配置文件,满足Zabbix需求源码安装Zabbix修改Zabbix基本配置初始化Zabbix监…http://www.yqsx.cn/news/382627.html
7.基木鱼常见问题解答A:页面模板制作的站点支持页面数据的统计,转化数据可以在营销通线索详单中查看。 38、百度统计能统计到基木鱼站点情况吗? A:基木鱼是接入的百度统计能力,可以统计到站点情况的数据。 39、基木鱼在保护客户的商业数据方面有什么功能? A:线索数据脱敏处理,手机二次验证才能下载。 http://www.qiqiyu.cn/5215
8.做网站页面的视频/网络营销推广方案模板做网站页面的视频,网络营销推广方案模板,网站的收费窗口怎么做,长沙手机网站制作Ubuntu 9.10很快就要发布了,估计它的开发人员跟我们产品开发人员大同小异,这段时间都可能比较忙,要处理很多BUG。 我前些天试用Ubuntu,遇到一个异常,然后自动报告BUG的机制启动了,我沿着它的流程注册登录了… http://www.nhpp.cn/news/104581.html
9.如何设计实现H5营销页面搭建系统营销活动可视化配置h5鉴于这种场景,内部也进行了很多的讨论。得出的一致结论就是:开发同学提供营销搭建后台,页面做成可配置化,配置的工作交给产品/运营同学。这样,基于楼层搭建营销页面的方案就应运而生了。 其实楼层搭建在营销页面的搭建中是一种比较常见的方式。 如上图是京东的一个活动页面,页面主要由三部分组成:头图楼层、优惠卷楼层https://blog.csdn.net/MrWeb/article/details/120562842
10.淘宝销售信息模板怎么改?是什么意思?淘宝销售信息模板怎么改?是什么意思? 进入宝贝页面,点击右上角的“编辑宝贝”对宝贝详情、宝贝属性等进行修改(如拍卖的宝贝已经有人出价,则无此按钮);若需要修改“仓库中的宝贝”,请您进入“我的淘宝”—“我是卖家”—“宝贝管理”—“出售中的宝贝”或“仓库中的宝贝”页面,找到对应宝贝记录,点击“编辑宝贝”https://www.maijia.com/article/515506
11.网站FAQ页面应该怎么去做网站FAQ页面应该怎么去做 FAQ 是 Frequently Asked Questions 的缩写,译为“常见问题”。与旨在转化消费者的着陆页不同,常见问题页面(FAQ)是你网站的一部分,你可以通过它解决顾客的常见担忧、疑问和异议。 图片来源:图虫创意 FAQ页面不仅仅是用于解答与业务相关的常见问题。这只是它的功能之一。https://www.cifnews.com/article/132836
12.二手车市场策划方案8、在页面模板头部添加。 9、为频道LOGO添加Alt说明。 三、站内优化—网站地图 1、html 网站地图: 为搜索引擎建立一个良好的导航结构 横向和纵向地图: 01.横向为频道、栏目、专题;02.纵向主要针对 关键词 每页都有指向网站地图的链接 四、站内优化—关键词 https://www.99xueshu.com/w/filed29dxmxf.html
13.网站策划方案模板(精选11篇)如产品中心使用动态程序数据库还是静态页面。营销网络是采用列表方式还是地图展示。 网站策划方案模板11 一、市场分析 1、相关行业的市场是怎样的,有什么样的特点,是否能够在互联网上开展公司业务。 2、市场主要竞争者分析,竞争对手上网情况及其网站规划、功能作用。 https://m.ruiwen.com/word/wangzhancehuafanganmuban.html
14.H5页面制作/电子邀请函模板/海报模板/问卷模板/互动营销模板人人秀提供海量的模板,可以快速创建和分享海报、H5页面、问卷、文章、长页、互动、应用、画册、小游戏、抽奖、答题等多种在线营销素材,满足个人、团队、企业的各种营销活动需求https://rrx.cn/
15.网络营销策划方案模板(通用15篇)网络营销策划方案模板(通用15篇) 为了确保工作或事情有序地进行,常常要根据具体情况预先制定方案,方案是从目的、要求、方式、方法、进度等都部署具体、周密,并有很强可操作性的计划。怎样写方案才更能起到其作用呢?下面是小编帮大家整理的网络营销策划方案,欢迎阅读与收藏。 https://www.yjbys.com/cehuashu/2580005.html
16.易优CMS企业建站系统稳定安全易用易优cms前端模板页面需要以列表形式调用全站会员信息时,该如何使用标签调用呢?请参考下面代码。{eyou:memberlist row= modelsartlist如何支持ID判断 2023-08-24 当使用modelsartlist标签时,需要判断对应ID来展示不同的样式,如何使用标签调用呢?下面调用标签就是判断栏目ID为2时显示样式二, https://www.eyoucms.com/
17.易企秀免费H5模板AI在线设计海报视频数字人同行都在用的H5模板 查看更多 创建作品 H5 会员免费用 寒假旅游创意境外意大利六日游宣传活动 nzhu 3 H5 会员免费用 商务鎏金新中式会议活动年会盛典招商答谢会邀请函 MOGU设计 29 H5 会员免费用 元旦节春节廉洁过节倡议书活动邀请函节日祝福h5 17品牌设计机构 https://www.eqxiu.com/
18.阿里试用营销活动购物指南 免费注册 开通支付宝 支付宝充值 天猫保障 发票保障 售后规则 物流时效保障 支付方式 快捷支付 信用卡 余额宝 蚂蚁花呗 商家服务 天猫规则 商家入驻 商家中心 天猫必修课 喵言喵语 平台服务协议 手机天猫 关于天猫 商家服务大厅 开放平台 诚聘英才 联系我们 网站合作 法律声明 隐私权政策 知识产权https://try.tmall.com/
19.企业培训市场营销网站网页模板企业培训市场营销网站网页模板-企业培训网站模版【编号:DENGLIE009-12】登烈模版网演示站点 本套网站模板由登烈提供相关服务;包含电脑网站、手机网站、自适应网站等多端合一的网站,包含服务器、二级域名、数据库 ,适用于企业培训相关业务行业;可按需求选择对应的版本进行搭建网站,提供3000+款网页模板免费体验使用。更多https://jz.denglie.com/DENGLIE009/12.html
20.如何做淘宝无线端手机店铺装修详细步骤2022在当下无线营销发展的大趋势大环境下,掌控好无线端营销的方向就等于握住了网络营销发展的咽喉。而要想做好手机店铺营销,首先要做的是无线端手机店铺的装修。如何做?详细教程,小编在以下为大家讲解到。 (一)手机装修页面进入 1、手机装修入口 店铺管理子类目下--手机淘宝店铺 http://www.seo-lv.com/zxzs/171.html
21.图片免费下载html网页首页模板素材html网页首页模板模板千图网为您找到103张html网页首页模板相关素材,千图网还提供html网页首页模板图片,html网页首页模板素材, html网页首页模板模板等免费下载服务,千图网是国内专业创意营销服务交易平台,一站式解决企业营销数字化、协同化,实现营销转化效果增长!https://www.58pic.com/tupian/htmlwangyeshouyemoban.html
22.WordPress外贸网站主题MB0050 是一套用于搭建建筑用车、重工机械、车床机械产品的WordPress产品营销模板。 注:以下介绍的图片可能不是这个模板的,但是主题、插件和功能框架都是一样^_^ 强大的可视化页面构建器 采用500万+ 安装量的最流行的 Elementor 可视化页面构建器 + 高级扩展程序,多达几十个可用小工具,轻松制作各种复杂布局需求。 除https://www.wpdaxue.com/shop/132762.html
23.SEO网站页面需求文档怎么写网站页面需求文档撰写教程以上就是关于如何在没有PM的前提下中小企业的非优化人员怎么写一个轻页面开发需求文档 ,当然在飞优看来,术页有专攻,若您的企业主正面临做站或网站改版的情形,你也不想自己操刀,那就联系飞小优吧,我们竭诚为您服务! 以下是飞优在易仓时做的网站改版项目,或许对此时的你有帮助!https://www.funion.co/6424.html
24.好模板网好模板网-制作网页的模板 查看更多案例 营销型网站 借力营销技巧 获取网站效益 营销型网站,是在网站建设中整合营销技巧和营销手法,通过对网站构架、页面布局的有机调整,突出展示产品服务,最终帮助企业拓宽商业渠道,获取商业订单。尘凡科技独具匠心,将多年来的营销经验转化在网站建设中,利用营销型网站,企业可以轻松实施营https://www.021van.com/web/204981.html
25.亚马逊A+页面是什么意思?亚马逊A+页面怎么做?亚马逊A+页面怎么做? 亚马逊A+页面(Enhanced brand content)是一种用于介绍亚马逊商品的高级展示工具,主要适用于品牌备案的卖家。该功能的主要目的是通过结合生动的图像、视频以及精彩的文字描述,为潜在顾客提供更详细、吸引人的产品信息。亚马逊A+页面可以被视为商品详情页的升级版,类似于淘宝、京东等电商平台上的详细https://www.dealshuo.com/amazon-a-plus-ye-me/