您当前的位置: 首页 > 

寒冰屋

暂无认证

  • 2浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Odoo10教程---模块化二:模型间关系,继承,计算字段等

寒冰屋 发布时间:2018-05-03 20:32:44 ,浏览量:2

模型之间的关系

来自模型的记录可能与来自另一模型的记录相关。例如,一个销售订单记录和一个包含客户数据的客户记录相关;同时也和销售订单线记录相关。

练习

创建会话模型

对于模块Open Academy,我们考虑一个会话模型:会话是在给定时间为给定听众授课的课程。

为会话创建模型。一个会话有一个名字,一个开始日期,一个持续时间和一些座位。 添加一个动作和菜单项来显示它们。通过菜单项使新模型可见。

  1. 在openacademy/models/models.py中创建类Session 
  2. 在openacademy/view/openacademy.xml中添加对会话对象的访问

openacademy/models.py

    name = fields.Char(string="Title", required=True)
    description = fields.Text()


class Session(models.Model):
    _name = 'openacademy.session'

    name = fields.Char(required=True)
    start_date = fields.Date()
    duration = fields.Float(digits=(6, 2), help="Duration in days")
    seats = fields.Integer(string="Number of seats")

openacademy/views/openacademy.xml

        

        
        
            session.form
            openacademy.session
            
                
                    
                        
                            
                            
                            
                            
                        
                    
                
            
        

        
            Sessions
            openacademy.session
            form
            tree,form
        

        
    

digits=(6, 2) 指定浮点数的精度:6是数字的总数,而2是逗号后的位数。注意逗号之前的数字的位数最大为4

关系字段

关系字段链接记录,即相同模型(层次结构)或不同模型之间的记录。

关系字段类型为:

Many2one(other_model, ondelete='set null')

与其他对象的简单链接:

print foo.other_id.name

请参阅

foreign keys

One2many(other_model, related_field)

一个虚拟关系,一个Many2one的逆关系。One2many 表现为一个记录容器,访问它导致一组(可能是空的)记录集合:

for other in foo.other_ids:
    print other.name

危险

因为One2many是一个虚拟关系,所以必须在other_model中有一个Many2one字段,它的名字必须是related_field

Many2many(other_model)

双向多重关系,任何一方的记录都可以与另一方的任何数量的记录相关。作为记录容器,访问它也会导致一个可能的空记录集:

for other in foo.other_ids:
    print other.name

练习

多对一关系

使用many2one,修改Course 和Session模型,以反映它们与其他模型的关系:

  • course有一个responsible用户;那个字段的值是内置模型res.users的记录
  • session有一个instructor;该字段的值是一个内置的模型res.partner记录
  • session和course是相关的;其字段的值是模型openacademy.course的记录,也是必须的
  • 适配视图
  1. 将相关的Many2one字段添加到模型中,以及
  2. 在视图中添加它们

openacademy/models.py

    name = fields.Char(string="Title", required=True)
    description = fields.Text()

    responsible_id = fields.Many2one('res.users',
        ondelete='set null', string="Responsible", index=True)


class Session(models.Model):
    _name = 'openacademy.session'
    start_date = fields.Date()
    duration = fields.Float(digits=(6, 2), help="Duration in days")
    seats = fields.Integer(string="Number of seats")

    instructor_id = fields.Many2one('res.partner', string="Instructor")
    course_id = fields.Many2one('openacademy.course',
        ondelete='cascade', string="Course", required=True)

openacademy/views/openacademy.xml

                    
                        
                            
                            
                        
                        
                            
            
        

        
        
            course.tree
            openacademy.course
            
                
                    
                    
                
            
        

        
        
        
            session.tree
            openacademy.session
            
                
                    
                    
                
            
        

        
            Sessions
            openacademy.session

练习

逆一对多关系

使用逆关系字段one2many,修改模型以反映courses 与sessions之间的关系

  1. 修改 Course 类,并且
  2. 在course 表单视图中添加字段

openacademy/models.py

    responsible_id = fields.Many2one('res.users',
        ondelete='set null', string="Responsible", index=True)
    session_ids = fields.One2many(
        'openacademy.session', 'course_id', string="Sessions")


class Session(models.Model):

openacademy/views/openacademy.xml

                            
                                
                            
                            
                                
                                    
                                        
                                        
                                    
                                
                            
                        
                    

练习

多重多对多关系

使用关系字段many2many,修改Session模型以将每个session 与一组attendees联系起来。Attendees 将由partner 记录表示,因此我们将关联内置的模型res.partner。相应地调整视图。

  1. 修改 Session 类,并且
  2. 在表单视图中添加字段

openacademy/models.py

    instructor_id = fields.Many2one('res.partner', string="Instructor")
    course_id = fields.Many2one('openacademy.course',
        ondelete='cascade', string="Course", required=True)
    attendee_ids = fields.Many2many('res.partner', string="Attendees")

openacademy/views/openacademy.xml

                                
                            
                        
                        
                        
                    
                
            
继承 模型继承

Odoo提供了两种继承机制,以模块化方式扩展现有模型。

第一个继承机制允许一个模块修改另一个模块中定义一个模型的行为:

  • 将字段添加到模型中
  • 重写模型上字段的定义
  • 向模型添加约束
  • 将方法添加到模型中
  • 重写模型上的现有方法

第二继承机制(委托)允许将模型的每个记录链接到父模型中的记录,并提供对父记录的字段的透明访问。

请参阅

  • _inherit
  • _inherits
视图继承

代替修改现有的视图(通过重写它们),Odoo提供的视图继承让子视图“扩展”的视图应用在顶部的根视图,并可以从父视图中添加或删除内容。

扩展视图使用inherit_id字段引用它的父类,而不是单个视图,其arch字段由任意数量的xpath元素组成,它们选择和改变父视图的内容:



    id.category.list2
    idea.category
    
    
        
        
          
        
    

expr

在父视图中XPath表达式选择单个元素。如果不匹配元素或多于一个,则会引发错误

position

应用于匹配元素的操作:

inside

在匹配元素的末尾追加xpath的body

replace

替换使用xpath的body的匹配元素,替换任何 $0 节点发生在使用原始元素的新的body中

before

在匹配元素之前插入xpat的body作为兄弟

after

匹配元素之后插入xpat的body作为兄弟

attributes

使用在xpath的body中的特殊的attribute元素改变匹配元素的属性

提示

当匹配一个元素,position 属性可以直接设置在元素上以便被发现。下面的两个继承将给出相同的结果


    



    

练习

更改现有内容

  • 使用模型继承,修改现有的Partner 模型以添加instructor布尔字段,以及对应于session-partner关系的many2many 字段
  • 使用视图继承,在partner表单视图中显示此字段

这是引入开发者模式来检查视图、找到其外部ID和放置新字段的位置的机会

  1. 创建文件 openacademy/models/partner.py 并在 __init__.py中导入
  2. 创建文件 openacademy/views/partner.xml 并在__manifest__.py中添加

openacademy/__init__.py

# -*- coding: utf-8 -*-
from . import controllers
from . import models
from . import partner

openacademy/__manifest__.py

        # 'security/ir.model.access.csv',
        'templates.xml',
        'views/openacademy.xml',
        'views/partner.xml',
    ],
    # only loaded in demonstration mode
    'demo': [

openacademy/partner.py

# -*- coding: utf-8 -*-
from odoo import fields, models

class Partner(models.Model):
    _inherit = 'res.partner'

    # Add a new column to the res.partner model, by default partners are not
    # instructors
    instructor = fields.Boolean("Instructor", default=False)

    session_ids = fields.Many2many('openacademy.session',
        string="Attended Sessions", readonly=True)

openacademy/views/partner.xml


 
    
        
        
            partner.instructor
            res.partner
            
            
                
                    
                        
                            
                            
                        
                    
                
            
        

        
            Contacts
            res.partner
            tree,form
        
        
        
    

在Odoo中,域是对记录条件进行编码的值。一个域是一个列表,用于选择一个模型的记录子集的标准。每个标准是一个三元组,有一个字段名、一个运算符和一个值。

例如,当使用Product 模型下列域选择所有是服务且单价超过1000的产品:

[('product_type', '=', 'service'), ('unit_price', '>', 1000)]

默认情况下,标准使用隐式的AND联合。逻辑运算符 & (AND), | (OR) 和! (NOT)可用来显示的联合标准。它们在前缀位置中使用(操作符在其参数之前插入而不是在它们之间)。例如,选择合适的产品“其是服务或有单价不是在1000和2000之间”:

['|',
    ('product_type', '=', 'service'),
    '!', '&',
        ('unit_price', '>=', 1000),
        ('unit_price', '
            
关注
打赏
1665926880
查看更多评论
0.0469s