美文网首页odoo
入坑odoo 三(创建自定义模块(1))

入坑odoo 三(创建自定义模块(1))

作者: vitermo | 来源:发表于2018-12-30 01:06 被阅读0次

    前提:odoo python3安装完成,如若未能完成安装,请查看我之前的文章,可能对你有所帮助。
    入坑odoo 一 (postgresql安装)
    入坑odoo 二(odoo12安装)
    本人也只是一边学习,一边记录学习的过程,如果对各位小伙伴有用,那便是极好的。同样,可能文章中有错的地方,如果各位小伙伴发现了,请给我留言,谢谢!
    OK,那么开始正题。

    创建模块
    1.我们在odoo源码所在的目录创建一个文件夹mkdir mymodules,mymodules是文件的名字,也可以根据自己的想法取。这个文件专门用于存放我们自己创建的模块,也和odoo自带的模块分开来。
    2.使用odoo-bin的脚手架创建一个空的odoo模块,里面包含来一个完整项目所需的基本文件和项目结构。

    #在终端进入odoo项目文件,输入以下命令
    ./odoo-bin scaffold todo mymodules    
    #todo是我们创建的模块名字,mymodules,是我们存放模块的文件目录
    

    结构说明
    todo
    ├── init.py
    ├── manifest.py
    ├── controllers
    │ ├── init.py
    │ └── controllers.py
    ├── demo
    │ └── demo.xml
    ├── models
    │ ├── init.py
    │ └── models.py
    ├── security
    │ └── ir.model.access.csv
    └── views
    ├── templates.xml
    └── views.xml
    具体结构就是这样,但你们让我说,我说不明白,如果小伙伴想知道的话,本人推荐一个odoo 教程系列,我也是从那学的,地址
    OK,结构说明我们就算过了哦。

    创建模型
    首先打开 models/models.py 将里面注释掉的内容删掉,不要修改文件顶部引入的包,然后添加以下代码:

    class TodoTask(models.Model):
         _name = 'todo.task'
         _description = '待办事项'
    
         name = fields.Char('描述', required=True)
         is_done = fields.Boolean('已完成?')
    

    看起来十分简单,第一个模型就这样创建好了 :)

    我们创建了一个叫做 TodoTask 的类,它继承自基础模型 models.Model,这也是我们使用 Odoo 开发时最常用的一种用于持久化数据的基础模型,除此之外还有 models.TransientModelmodels.AbstractModel 这两种,在之后接触到我们将会进行讲解,这里暂不涉猎。

    先看一下这个模型里带下划线前缀的两个属性:

    _name - 模型的名称,在外键或者实例化模型对象时会用到,是模型的唯一标识
    _description - 模型的描述,描述模型的作用,一般情况下不会主动使用到
    除了上面列出的两个特殊属性外,还有一些其他属性,例如更改默认显示名称时会用到 _rec_name,继承现有模型时会用到 _inherit 等,这些特殊属性都具有他们各自的用途,但是除了 _name 是定义一个新的模型时必须要有的属性外,其他属性都是可选的。

    在 Odoo 的模型定义中,我们使用 fields 进行字段的定义,在上面这个模型里,我们简单地定义了 nameis_done 两个字段,它们的类型分别是 CharBoolean,并且我们指定字段 name 是必填的(添加了required=True)。如果小伙伴接触过 Django,可能就会说了,DjangoCharField 是必须指定最大长度 max_length 的,Odoo 的不需要吗?那最大长度是多少呢?对于这个疑问,官方的文档里有这样一句说明:

    Basic string field, can be length-limited, usually displayed as a single-line string in clients.

    也就是说 Odoo 的字段类型 Char 是不限制长度的,但是通常只是用于单行字符串,如果要存储大量文本内容,还是使用 Text 更合适一些。
    接下来,我们需要在odoo.conf文件的addons_path中添加/Users/vitermo/odoo12/mymodels,vitermo是我们的电脑用户名称,mymodels是我们存放模块的文件夹,可以根据自己的情况进行修改。
    接下来我们打开浏览器访问 localhost:8069 然后用超级管理员帐号登录(不记得了?帐号密码都是 admin),登录后在应用列表页面,将搜索框的 Apps 标签去掉,搜索关键词 todo 找到我们刚创建的模块,点击 Install 按钮安装模块。好了,你很快就会发现,页面又倒回了应用列表页面,如果我们再次按前面的步骤搜索我们的模块,你会发现没有了安装按钮,现在显示的是 Installed 已安装,除了这个变化外仿佛一切都没发生过,这是为什么呢?

    因为我们没有入口,找不到可以打开我们的 Todo 应用的地方,接下来我们就一起创建第一个入口——菜单。
    创建菜单
    光有模型是当然不够的,就好象一幢大楼,钢筋骨架都搭起来了,然后把墙给封死了,没有门我们进不去呀!

    刚好像说了个不怎么恰当的比喻,不如直接动手,创建一个菜单更实际。在模块里的 views 目录下创建一个 menus.xml 文件,然后输入以下内容:

    <?xml version="1.0" encoding="utf-8"?>
    <odoo>
        <data>
            <!-- 主菜单定义 -->
            <menuitem id="menu_todo" name="Todo"/>
            <!-- 菜单动作定义 -->
            <record id="action_todo_task" model="ir.actions.act_window">
                <field name="name">待办事项</field>
                <field name="res_model">todo.task</field>
                <field name="view_type">form</field>
                <field name="view_mode">tree,form</field>
                <field name="target">current</field>
            </record>
            <!-- 子菜单定义 -->
            <menuitem action="action_todo_task" id="submenu_todo_task" name="待办事项"
                      parent="menu_todo" sequence="10"/>
        </data>
    </odoo>
    

    上面各部分内容我都写上了备注,大家一看就应该知道它们各自是干什么的了。在 Odoo中定义一个菜单,使用的是 menuitem,然后我们需要为菜单指定属性 idname,前者是这个菜单的唯一标识,而后者则是这个菜单所显示的名字。

    然后我们定义了一个菜单动作,也就是点击一个菜单时所要执行的动作,Odoo 中动作的类型分为几个类型,从 model 这个属性可以看出来一个动作是属于什么类型的,act_window表示我们定义的这个动作是和窗口有关的,例如打开一个弹窗或者一个列表页面,都可以通过窗口动作实现。其他类型的动作我们先放一放,后面会有专门的一篇文章用于讲述动作相关的内容,我们先简单地了解一下定义一个窗口动作有哪些要素。

    和定义菜单一样,必不可少的会有 id 这一属性,以后我们将默认所有在 .xml文件中定义的数据,都需要带有 id 属性,毕竟这是我们能够通过代码找到它们的唯一标识了。这里我们用了 record 标签,包裹了一系列的 field 来定义我们的动作,除了可以定义动作外,包括前面提到的菜单在内的一切具有实际模型的对应的数据,我们都可以这样定义,最大的区别就在于 model这个属性所指定的值,它对应到我们定义的数据是来自哪个模型的,被包裹在里面的 field 则对应到一个模型的各个字段。刚开始可能不太明白,不过不要紧,后面会一直使用到,很快就能掌握的了。

    最后我们定义了一个子菜单,可以看到和最开始定义的菜单不一样的是,我们这里多了 3 个属性,分别是 actionparentsequence。其中 action 的值是我们定义的动作的id,表示点击这个菜单,就执行对应 id 的动作,parent指定的值是我们定义的第一个菜单的 id,表示当前菜单是指定菜单的子菜单,sequence 用于指定当前菜单的位置,如果我们在主菜单下有多个子菜单,我们可以通过这个属性去指定各个子菜单排列的先后顺序。

    关于菜单和动作,暂时就先到这里,最后不要忘了把文件 menus.xml放到__manifest__.pydata 列表中,不然我们定义的内容是不会被加载的哦:

    # 现在应该是这样的
    'data': [
        #'security/ir.model.access.csv',
        'views/views.xml',
        'views/templates.xml',
        'views/menus.xml',
    ],
    

    #'security/ir.model.access.csv',,注释去掉,并且进入到security/ir.model.access这个文件中,将其修改成如下图:

    id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
    access_todo_task,todo.task,model_todo_task,,1,1,1,1
    

    后面几个数字是权限的一些东西,目前我不知道怎么用,索性我全部都给你。
    好咧,菜单有了,也就有了入口,现在我们刷新页面看看有没有什么变化,好像还是一样没有什么不一样?当然了,因为我们修改了模块里的文件内容,这些变动并没有被加载,所以我们需要先升级模块。一样的步骤,先找到我们的 Todo 应用模块,然后点击卡片进入表单页面,可以看到有个 Upgrade(升级) 按钮,我们点击这个按钮把模块升级一下,然后你就会发现,我们终于看到了期待已久的菜单和 Todo 应用的列表页面啦~

    屏幕快照 2018-12-30 上午12.50.58.png
    各位可以创建自己的数据来,页面展示的是本人创建的数据
    还记得在创建模型的时候给字段 name 加上了一个 required=True 的属性吗?在创建记录的表单页我们可以看到,这个字段是淡紫色背景的,这说明这一项是必填的内容,如果不填写,点击 Save(保存) 按钮,就会发现标签显示的「描述」变成了红色,输入框也被红色边框包裹起来了,并且可以看到在窗口右上角出现了一个警告提示。
    在创建好一条待办事项的记录后,点击 Save 保存,如果想要继续创建,可以直接在表单页上点击 Create 继续创建新的记录,也可以返回列表页查看全部的待办事项记录。如果完成了一个待办事项,我们点击对应的记录,进入到表单页面,然后点击 Edit 编辑按钮,然后勾选「已完成?」表示我们已经完成了这个任务。

    想要删除掉一些记录该怎么办?可以在列表页先勾选需要删除的记录,然后点击上面的 Action 菜单,可以看到 Delete这个选项,点击后会询问是否要删除,点击 Ok 确认就可以删除啦~除了列表页上可以删除记录,还能打开一条待办事项进入表单页面,然后打开 Action 菜单执行删除操作

    创建视图
    在创建菜单之后,我们直接就看到了相应的列表和表单页面,可是我们并没有创建任何相关的内容,这是 Odoo 自动帮我们做了处理。如果一个模型没有创建对应的视图(View),Odoo 就会根据默认的规则进行显示。

    可是默认在列表页只显示了一个 name字段,我们想要知道一个事项是否完成了,并不能直接在列表页上知道,需要一个个点击进去查看,如果有很多的记录,这可就太蛋疼了!所以我们还是需要自己创建一个列表视图,把是否已完成显示在列表页上。

    打开 views/views.xml,把里面注释掉的内容都删掉,然后添加以下内容:

    <odoo>
        <data>
            <record id="todo_task_view_tree" model="ir.ui.view">
                <field name="name">todo.task.view_tree</field>
                <field name="model">todo.task</field>
                <field name="type">tree</field>
                <field name="arch" type="xml">
                    <tree string="Todo">
                        <field name="name"/>
                        <field name="is_done"/>
                    </tree>
                </field>
            </record>
        </data>
    </odoo>
    

    创建视图相关的内容,我们需要指定属性 model="ir.ui.view",然后还有两个关键的地方是 type 的值,如果创建的是列表视图,则填写 tree,如果是表单视图则是form,除了这两种视图外还有其他类型的视图,我们暂时不会接触到。然后是 arch 的值,里面的内容决定了我们的视图长什么样,列表视图需要用 <tree></tree>包裹起来,表单视图则是 <form></form>,包裹的内容具会有所不同,这里我们只需要在列表视图中将要显示的字段列举出来即可。

    完成这一切之后,升级一下模块,然后看看效果如何。 image.png

    可以看到列表里多了一列「已完成?」,这样我们就可以一目了然,知道哪些事项是已经完成了的,然后就可以直接勾选将他们删除掉啦 XD

    本文大量摘抄odoo基础教程,如若原作者不同意请联系本人,本人立马删除该文章。同时,本人推荐各位同学可以去原作者的文章进行学习,本文只是个人在学习odoo时的记录,以便后续查看。如有对原作者损害,实属抱歉。

    相关文章

      网友评论

        本文标题:入坑odoo 三(创建自定义模块(1))

        本文链接:https://www.haomeiwen.com/subject/vcumlqtx.html