zoukankan      html  css  js  c++  java
  • Odoo10学习笔记三:模型(结构化的应用数据)、视图(用户界面设计)

    原文地址:http://www.cnblogs.com/ygj0930/p/7115315.html

    一:模型

    【Odoo中,一切皆模型,连视图都是模型。Odoo将各种数据,如:权限数据、类数据、视图数据等,按照模型分表存储,然后在查看时,按照索引从各个表格读取信息,组合成我们看到的内容。】

    1:创建模型

    模型属性:模型类可以使用一些属性来控制它们的一些行为:

    _name :创建odoo模型的内部标识符,必含项。

    _description :当用户界面显示模型时,一个方便用户的模型记录标题。

    _order :当浏览模型记录或者显示在列表视图时,设置默认顺序。

    _rec_name:用来指出引用关联字描述记录的字段,例如多对一关系。 默认情况下,它使用name字段,这是模型中常见的字段。但是这个属性允许我们使用任何其他字段来实现这个目的。

    _table:用来支持模型的数据库表名。通常,它是左自动计算,是下划线取代点的模型名称,但也可以设置特定的表名。

    _inherit :继承。

    _inherits :嵌入式继承。

    模型深入:

    Odoo模型由Python类表示。

    Odoo模型被保存在一个中央注册中心,它可以引用实例中可用的所有模型类,并且它可以被一个模型名引用。在我们编写的模型方法代码中,可以通过 self.env['x'] 获取一个代表model x的类的引用。(相当于spring托管对象)

    模型名称很重要,因为它们是用于访问注册中心的。模型名称的约定规则:用点分隔的小写字母列表。

    模型名称必须是全局唯一的。正因为如此,第一个词应该对应于该模块涉及到的主要应用程序。
    瞬态和抽象模型:

    绝大多数Odoo模型中,类都是基于models.Model类的。 这种类型的模型具有永久的数据库持久性:为它们创建数据库表,并且它们的记录被存储,直到被显式删除。

    Odoo还提供了另外两种模型类型:瞬态模型和抽象模型。

    瞬态模型基于models.TransientModel类,用于向导式的用户交互。 它们的数据仍然存储在数据库中,但期望是临时的。 一个清理作业定期从这些表中清除旧数据。 
    抽象模型基于models.AbstractModel类,并且它不存储数据。 抽象模型作为可重用的功能集,利用Odoo的继承功能,混入到其他模型。


    2:模型之间的关系

    命名字段时,有以下约定:以_id、_ids为结尾命名的字段,分别对应的是2one和2many的关系。

    多对一关系:Many2one关系需要两个参数:关联模块和展示字符。它会在数据库表中创建一个拥有外键的字段去关联数据库表。其他参数:
    ondelete 在关联的记录被删除时,将会触发。默认值是null,也就是说,当关联的记录被删除时,它将被置空。其它值为restrict,当记录被关联时,禁止删除,cascade,删除关联记录的同时删除当前记录。
    context是一个数据字典,在web客户端视图,通过关联关系访问时,会将上下文传过去。比如,设置默认值。它的详细的介绍,在第六章-视图-设计用户界面中。
    domain是一个由多个元组组成的列表的域表达式,用来删选关联字段中有效的记录。
    auto_join=True使用这个参数后,将允许ORM在数据查询是使用SQL的join(拼接,级联)功能。
    多对多关系:Many2many 最少要提供一个参数,也就是关联的模块,建议再使用string参数,以便更好的标题展示。
    多对多关系的存储:在数据库层面,数据库表中是不会添加任何字段。它会自动的创建一个新的中间表,这个表只有两个外键ID字段,并且这两个字段分别关联对应的数据库表。

    一对多反向关系:One2many按顺序接收3个参数:关联的模块,关联模块的字段名称,标题文本。最开始的两个参数通常是模块名和相反关系对应的外键字段名。
    分层关系:树型存储。

    _parent_store = True
    # _parent_name = 'parent_id'
    parent_id = fields.Many2one('todo.task.tag', 'Parent Tag', ondelete='restrict')
    parent_left = fields.Integer('Parent Left', index=True)
    parent_right = fields.Integer('Parent Right', index=True)
    #添加一个子记录
    child_ids = fields.One2many('todo.task.tag', 'parent_id', 'Child Tags')


    3:计算字段

    要创建计算字段,需要设置它的compute属性为方法名。这个计算方法通过计算self的每条记录来设置字段的值。

    注意
    self是一个记录的有序集合,它支持标准的Python集合操作,如len(self)iter(self),加上额外的集合操作recs1 + recs2。迭代过程逐个提供self记录,其中每个记录本身是大小为1的集合。你可以通过点记号来访问/分配单个记录上的字段record.name

    计算字段就像常规字段一样声明,但是有额外的compute参数,参数值是一个函数名,在函数中计算值并返回。

    字段= fields.XX(compute='函数名')
    @api.depends('参数')
    def 函数(self):
        操作


    当计算依赖于其他字段时,需要@api.depends装饰器。

    计算字段的值通常取决于所在记录行的其它字段的值。ORM层期望开发人员使用depends()装饰器来指定计算方法的依赖性。当某些依赖关系被修改后,ORM层通过给定的依赖关系来触发字段的重新计算

    一种用法:统计一对多字段的长度,得到关联人数:

    attendees_count = fields.Integer(string="Attendees count", compute='_get_attendees_count', store=True)
    @api.depends('attendee_ids')
    def _get_attendees_count(self):
        for r in self:
            r.attendees_count = len(r.attendee_ids) //根据关联字段的长度,得到出席人数

    onchange:【onchange相当于前端的js函数!】

    "onchange"机制为客户端界面提供了一种方法:当用户在字段中填写了值,不需要向数据库保存任何内容,就可以更新表单。

    例如,假设模型有三个字段amount,unit_priceprice,当数量和单价改变时,自动重新计算价格,并在表单界面更新。要实现这个需求,需要定义一个方法,并使用onchange()装饰器,onchange()的参数指定了在那个字段改变时,触发方法。其中self代表表单视图中的记录,你所做的任何更改,self都将立刻反应在表单上。 

    onchange也可以用于检测字段变化值是否合法。

     

    搜索与写入:

    计算字段可以通过计算得到字段值,但此时只能被读取显示,还不能被搜索或者写入。为此,我们需要实现函数,并通过字段的search参数、inverse参数来实现该字段的搜索与写入定义。

    复制代码
    字段= fields.XX(
    
    string='展示名',
    
    compute='计算函数',
    
    search='搜索函数',
    
    inverse='写入函数')
    
    
    def 搜索函数(self, 参数):
    
        return [('搜索条件', operator, value)]
    def 写入函数(self): self.字段 = self.写入值
    复制代码

    存储计算字段:通过设置“store= true”的定义,计算字段的值也可以存储在数据库中。

     

    4:关联字段

    字段 = fields.XX(
    
    related='关联模型.关联字段',
    
    string='展示名')

     

    5:模型约束

    Python约束检查函数应该使用@api.constraints(被约束字段) 修饰,说明被检查的字段的列表。当其中任何一个被修改,并且在条件失败时将会抛出一个异常,验证就会被触发。

    @api.constrains('字段名')
    def 验证函数(self):
        if 条件:
        raise ValidationError('验证错误信息!')

     

    6:self.env

    复制代码
    self.env 对象给出了访问请求参数和其他有用的信息:
    
    self.env.cr 或者 self._cr是数据库游标对象,通常用于查询数据库
    self.env.uid或者self._uid是当前用户的数据库ID
    self.env.user是当前用户记录
    self.env.ref(xml_id)返回XML ID对应的记录
    self.env[model_name]返回给定模型的实例
    复制代码

     

    二:视图

    用户界面的每个组件都以记录的形式存储在数据库中,模块从XML文件加载相应的数据时会向数据库添加UI元素,然后odoo从数据库读取UI元素进行显示。

    菜单项:

    <menuitem>快捷元素,提供了一种缩减方式来定义要加载的记录,我们可以使用它来代替<record model =“ir.ui.menu”>元素。

    顶级菜单项:只有id和name属性。

    子菜单项:通过parent =“上层菜单id”属性置于上层菜单下。

    菜单动作:通过action =“act_window”属性,把点击菜单的动作指定为act_window中打开某个视图(如tree/form)

    菜单分组:使用groups属性使其仅对某些安全组可见。

     

    窗口动作:

    给出GUI客户端指令,通常供视图中的菜单项或按钮调用。

    它告诉GUI应该使用什么模型,以及提供哪些视图。 这些操作可以使用domain过滤器强制只有一部分记录可见。 他们还可以通过context属性设置默认值和过滤器。

    窗口动作存储在ir.actions.act_window模型中,可以使用<act_window>快捷标签在XML文件中定义。

    主要属性有:

    复制代码
    name:通过此操作打开的视图中显示的标题。
    res_model:目标模型的标识符ID
    view_mode:要打开的视图类型和它们的顺序。 第一个是默认打开的。
    target:如果设置为new,将在弹出的对话框窗口中打开视图。 默认值为current,在主内容区域中打开视图。
    context:设置关于目标视图的上下文信息,上下文中可以设置默认值或激活过滤器以及其他信息。
    domain:域表达式,强制过滤在打开的视图中可浏览的记录。
    limit:列表视图中每个页面的记录数。

    src_model:应该在什么模型上此动作可用。

      multi:当设置为True时,使它在列表视图中可用,以便它可以应用于多条选中的记录。 默认值为False。

    复制代码

     

    上下文与域:

    context属性值:上下文是一个包含session数据的字典,它可以被客户端的用户接口和服务器端的ORM与业务逻辑使用。

    在客户端,它可以将信息从一个视图传输到另一个视图。在服务器端,一些记录的字段值可以通过上下文被本地设置提供。

    domain表达式:域被用来筛选数据记录。它们使用特殊的语法,以便于Odoo ORM 将它们解析后生成对应的SQL WHERE数据库筛选语句。

    域表达式是一个条件列表,每个条件是一个形如('field_name', 'operator', value')的元组。

    复制代码
    filed_name 是需要筛选的字段,它可以使用点(.)来访问关系模块的字段。
    value 是一个Python表达式的值。它可以使用字符值,比如:字符串,数字,布尔值,或则列表、某个字段、用户在context中自定义的有效的值。
    operator 可以为:
        常用的操作符:<,>,<=,>=,=,!=。
        '=like'通配符,使用下划线(_)时,匹配一个任意字符,使用百分号(%)时,匹配多个字符。
        'like'匹配一个’%value%’的字符串。’ilike’与此类似但不区分大小写。‘not like’和‘not ilike’也可以使用
        'child of'在层级关系中,筛选子集
        'in'和’not in’筛选是否在一个列表里面,所以,给的值应该是个list。当在’to-many’的关系字段中,‘in’的作用和contains的作用一样
    复制代码

    domain表达式是一个包含多项内容的list,因此,可以包含多个条件表达式元组。 默认情况下(隐含),这些条件之间是用AND逻辑符连接的,也就是说,它只返回满足所有条件的记录集。

    也可以用显式的逻辑连接符:and连接符(&,默认使用),或连接符(|)。这些连接符后面跟着两项内容,可以画成递归树的形式理解。

    感叹号(!),是非操作符(NOT),作用于紧挨它的后一个项。因此,它应该出现在否定项的前面。比如,['!', ('is_done','=',True)]

    ['|', ('message_follower_ids', 'in', [user.partner_id.id]),
          '|', ('user_id', '=', user.id), ('user_id', '=', False)]

    画成递归树:

     

     

     

    窗体视图:form视图

    Header头部:header区域一般用于展示文档流转的阶段和生命周期,以及动作按钮。

    文档生命周期通过状态栏小控件呈现当前所处的状态.这些通常是状态选择字段或者多对一的阶段字段。

    状态是一个选择列表,呈现的是过程中有几个相当稳定的步骤阶段,例如:新建、处理中、完成。

    操作按钮一般为表单按钮,最重要的阶段可以使用class=“oe_highlight”突出显示。

    Sheet区域:

    标题:在group之外,我们可以使用html基本元素来制定标题,如:div,span,H1,和H2等。

    分组:<newline>将强制生成一个新行。附加部分标题可以使用<separator>元素添加到组内。使用col和colspan属性,我们可以更好的控制组元素布局。col属性可以指定组中包含的列数,默认值是2,它也可以改为任何数字,双数的效果更好,因为每一个字段加起来都要两列。组内元素,包括<field>元素,可以使用colspan属性设置一个特定的列数,默认都是一列。

    分页笔记本:笔记本元素可以包含多个标签的部分,称为页面。可以实现按页切换输入、显示。

    复制代码
    <notebook>
    <page string="显示文字" name="页名">
      内容...
    </page> 
    <page> 
     ...
    </page>
    </notebook>
    复制代码

     

    语义组件:

    视图标签属性:

    name:标识字段数据库名称

    string:标签文本,如果我们想要覆盖模型定义提供的标签文本,可以使用它。

    help:提示文本,当您将指针悬停在字段上时,将显示一个提示文本,并允许覆盖模型定义提供的帮助文本。

    placeholder:是一个建议文本,显示在该字段内。

    widget:允许我们覆盖用于该字段的缺省小部件。

    options:是一个JSON数据结构,为小部件提供了额外的选项,并且取决于每个小部件支持什么。

    class:是用于字段HTML呈现的CSS类。

    nolabel="True":防止自动字段标签被呈现。仅对<group>元素中的字段有意义,并且经常和<label for="..."> 元素一起使用.

    invisible="True":使字段不可见,但是数据是从服务器获取的,并且在表单上可用。

    readonly="True": 使表单上的字段不可编辑。

    required="True" 在表单上字段为必需字段。

    某些字段类型的特殊属性:

    password="True":用于文本字段。它显示为一个密码字段,屏蔽输入的字符。

    filename: 用于二进制字段,它是用于存储上传文件名称的模型字段名称。

    mode:用于一对多字段。它指定用于显示记录的视图类型。默认情况下,它是树,但也可以是表单、看板或图形。

     

    小部件(widget属性值):

    对于文本字段,我们有以下小部件:

    email:是用来将电子邮件文本转换为一个可操作的“邮件”地址。

    url :用于将文本格式化为可单击的url。

    html:用于渲染文本作为html内容;在编辑模式下,以WYSIWYG编辑器,允许内容的格式,而不需要使用HTML语法。

    对于数值字段,我们有以下小部件:

    handle:是专门为列表视图中的序列字段设计的,并显示一个句柄,允许您将行拖到一个定制的顺序。

    float_time:拥有小时和分钟的时间浮点字段格式.

    monetary:作为货币金额显示浮动字段。它需要一个currency_id伙伴字段,另一个字段名称可以设置选项=“{ 'currency_field ':' currency_id“}”。

    progressbar 用一个浮点数表示为一个进度百分比,并且可以用于表示完成率字段.

    对于关系和选择字段,我们有这些附加的小部件:

    many2many_tags : 显示按钮标签列表值.

    selection:用于多对一字段的选择字段部件。

    radio 使用单选按钮显示选择字段选项.

    kanban_state_selection展示了看板状态选择列表的信号灯。一般状态为灰色,已经完成为绿色,其他状态为红色.

    priority 一个可点击的星星列表的选择字段。可选项一般为数字.

     

    按钮(button元素)属性:

    icon  可用的按钮图标在 addons/web/static/src/img/下

    string 按钮的显示文字

    type 是动作执行类型。可能值是:workflow, object,action   默认是 workflow:

        workflow 用于触发工作流引擎信号;

        object 用于调用Python方法;

        action 用于运行窗口动作。

    name 触发的方法标识:工作流信号名、模型方法名称或运行窗口操作的数据库ID。

    args 传递方法的参数

    context 将值添加到上下文

    confirm 针对对话框的确认

    special="cancel" 用于向导,用来取消和关闭向导表单。

    class 加载的类名(常用 oe_highlight)

     

    动态视图:

    视图元素也支持一些动态属性,允许动态视图根据字段值来改变他们的外观或行为。

     

    其他视图:

    日历视图:

    <field name="arch" type="xml">
    
    <calendar date_start="字段" color="颜色"
    
    display="[name], Stage [stage_id]" >

    日历视图属性:

    date_start开始日期的字段,必需字段。

    date_end结束日期的字段,可选字段。

    date_delay持续天数的字段,可以使用代替date_end。

    all_day提供一个布尔字段是用来发送全天事件信号。

    color 日历条目颜色分组的字段 。这个字段中的每个不同的值将被分配一个颜色,并且该字段所有同值的条目将具有相同的颜色。

    display 是每个日程表条目的显示文本. 它使用方括号加字段名称表示用户记录值,例如[name]。

    mode 是日历的默认显示模式,无论是一天、一周还是一个月。

     

    图形视图:

    <graph type="bar">
    
    ...
    
    </graph>

    图形视图元素可以有一个类型属性,可以设置为条形(默认)、饼状或线。在条形的情况下,可以使用stacked="True"呈现堆叠在一起的条形图。

     

    枢轴视图:

    <pivot>
    
    ....
    
    </pivot>
  • 相关阅读:
    ubuntu15.10下各种编译环境的搭建(工作平台大转移)
    win7+ubuntu15.10的安装
    Qt之串口通信
    读C++代码必备专业名词
    好书好网站积累着有空看
    大数学家与中小学教育相关的资料(持续更新)
    《x的奇幻之旅》读书笔记
    冯·诺依曼为后生解围
    从一道简单的几何题说起
    Steiner-Lehmus 定理
  • 原文地址:https://www.cnblogs.com/qjtjh/p/8269619.html
Copyright © 2011-2022 走看看