odoo

Packer.Odoo.10---Chapter 2

2017-09-26  本文已影响432人  F4A3

创建第一个odoo 应用

Odoo遵循传统的MVC模式。我们可以通过创建简单的To-Do 应用来具体介绍分析


理解applications(应用)跟modules(模块)的区别:

创建一个module基础架构
{
    'name': 'To-Do Application',  
    'description': 'Manage your personal task',
    'author': 'xer',
    'depends': ['base'],
    'application': True,
    'data': [ ],
}
  1. summary:module的次要标题
  2. version: 代码module的版本号
  3. license:版权,默认LGPL-3
  4. website:设置一个URL用来查找模块相应的信息
  5. category:module的分类,默认为Uncategorized。目前已存在的categories可以在Settings| User | Groups中找到
  6. installable: 默认为True
  7. auto_install: 如果设置为True 这个模块会自动安装.

添加todo_app到addons path
安装todo_app
image.png
更新module

服务端开发者模式
  1. 自动的Reload python代码.
  2. 自动的读取xml files中的新定义.避免手动更新

model 层:

创建一个data 模块:
# -*- coding: utf-8 -*-
from odoo import models, fields
class TodoTask(models.Model):
   _name = 'todo.task'
   _description = "To-do Task"
   name = fields.Char('Description', required=True)
   is_done = fields.Boolean('Done')
   active = fields.Boolean('Active?', default=True)

重启Odoo服务,由于我们还没定义菜单,需要进入Settings | Technical | Database Structure | Models.使用'todo.task'来搜索我们刚才定义的model.点击查询结果来查看.

image.png
添加自动测试

Odoo有2种测试方法:

  1. YAML
  2. Python的测试类(Unittest2).
下面主要介绍第二种测试方法:
from odoo.tests.common import TransactionCase
class TestTodo(TransactionCase):
    def test_create(self):
        'Create a simple Todo'
        Todo = self.env['todo.task']
        task = Todo.create({'name': 'Test Task'})
        self.assertEqual(task.is_done, False)

view层

添加 menu 主题
<?xml version="1.0"?>
<odoo>
   <act_window id="action_todo_task"
               name="To-do Task"
               res_model="todo.task"
               view_mode="tree,form"/>
 <!--menuitem -->
   <menuitem id="menu_todo_task"
             name="Todos"
             action="action_todo_task"/>
</odoo>

提升我们的视图
添加一个form视图
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
    <!--<form view>-->
    <record id="view_form_todo_task" model="ir.ui.view">
        <field name="name">To-do Task Form</field>
        <field name="model">todo.task</field>
        <field name="arch" type="xml">
            <form string="To-do Task">
          <group>
                    <field name="name"/>
                    <field name="is_done"/>
                    <field name="active" readonly="1"/>
                    </group>
            </form>
        </field>
    </record>
</odoo>

业务文档form视图
添加动作按钮(action buttons)
 <header>
       <button name="do_toggle_done" type="object" string="Toggle Done" class="oe_highlight"/>
        <button name="do_clear_done" type="object"  string="Clear All Done"/>
</header>

使用<group>来组织form视图
image.png

最后,我们的form视图代码如下:

            <form string="To-do Task">
                <header>
                    <button name="do_toggle_done" type="object"
                            string="Toggle Done" class="oe_highlight"/>
                    <button name="do_clear_done" type="object"
                            string="Clear All Done"/>
                </header>
                <sheet>
                <group name="top">
                    <group name="left">
                    <field name="name"/>
                </group>
                    <group name="right">
                        <field name="is_done"/>
                        <field name="active" readonly="1"/>
                    </group>
                </group>
                </sheet>>
            </form>

展示效果:

image.png
添加列举(list)跟搜索(search)视图
    <!--tree view-->
    <record id="view_tree_todo_task" model="ir.ui.view">
        <field name="name">To-do Task tree</field>
        <field name="model">todo.task</field>
        <field name="arch" type="xml">
            <tree colors="decoration-muted:is_done==True">
                <field name="name"/>
                <field name="is_done"/>
            </tree>
        </field>
    </record>
    <!--search view-->
    <record id="view_filter_todo_task" model="ir.ui.view">
    <field name="name">To-do Task Filter</field>
    <field name="model">todo.task</field>
    <field name="arch" type="xml">
        <search>
            <field name="name"/>
            <filter string="Not Done"
                    domain="[('is_done','=',False)]"/>
            <filter string="Done"
                    domain="[('is_done','!=',False)]"/>
        </search>
    </field>
    </record>

逻辑层

添加业务逻辑
@api.multi
def do_toggle_done(self):
      for task in self:
            task.is_done = not task.is_done
      return True
@api.model
 def do_clear_done(self):
        dones = self.search([('is_done', '=',True)])
        dones.write({'active': False})
        return True
添加测试
 def test_create(self):
        # Test Toggle Done
        task.do_toggle_done()
        self.assertTrue(task.is_done)
        # Test Clear Done
        Todo.do_clear_done()
        self.assertFalse(task.active)

使用./odoo-bin -d todo -i todo_app --test-enable

设置模块访问权限(access security)

当我们加载我们的模块时,记录中会有一条warning message:

The model todo.task has no access rules, consider adding one.

测试访问权限
    def setUp(self,*args,**kwargs):
        result = super(TestTodo, self).setUp(*args, **kwargs)
        user_demo = self.env.ref('base.user_demo')
        self.env = self.env(user=user_demo)
        return result
    def test_record_rule(self):
        'Test per user record rules'
        Todo = self.env['todo.task']
        task = Todo.sudo().create({'name': 'Admin Task'})
        with self.assertRaises(AccessError):
            Todo.browse([task.id]).name
  1. 因为我们现在的env 已经使用Demo用户,我们使用sudo()方法(可以理解为linux下的sudo)来切换到admin的上下文环境创立一个name为Admin Task的task。这么做的目的是创建一个不能被Demo所获取的to-do task.
  2. 当我们尝试使用Demo用户去获取上文创建的task时,会有一个AccessError异常被抛出.

添加访问控制

访问Settings | Technical | Security| Access Controls List:

image.png

这些信息是有模块提供然后加载到odoo中的'ir.model.access'模块,接下来,我们就在我们的model中添加所有权限给员工(employee)这个分组.注:员工这个分组是非常普通的.

id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_todo_task_group_user,todo.task.user,model_todo_task,base.group_user,1,1,1,1

CSV文件中的列名:
我们定义的CSV文件中,第一行的那些名字可以看做是书写的参照规则:


Row-level的访问规则

Setting | Technical | Record Rules
记录规则被定义在'ir.rule' model中,跟往常一样,我们需要提供一个特殊的名字,记录规则作用在的具体的model以及需要定义的domain过滤规则来进行权限约束。

<?xml version="1.0" encoding="utf-8" ?>
<odoo>
    <data noupdate="1">
        <record id="todo_task_user_rule" model="ir.rule">
            <field name="name">ToDo_rule</field>
            <field name="model_id" ref="model_todo_task"/>
            <field name="domain_force">[('create_uid','=',user.id)]</field>
            <field name="groups" eval="[(4,ref('base.group_user'))]"/>
        </record>
    </data>
</odoo>
添加一个module的图标
上一篇 下一篇

猜你喜欢

热点阅读