第三章 Odoo开发之模型字段

目录

1、基本字段类型

2、字段中可定义的参数 

3、保留字段名

 4、关联字段

 1、Many2one(多对一)

 2、Many2many(多对多)

3、 One2many(一对多)

用法总结

 关联字段的参数详解

 4、层级关联

层级关联的实现

层级关联的应用场景

5、引用字段的弹性关联(Reference字段)

引用字段的应用场景

6、计算字段

 计算字段的搜索,写入

关联字段 


1、基本字段类型

       在Odoo中,基本字段类型是用于模型(Model)的字段,它们用于存储各种类型的数据。以下是Odoo中常见的基本字段类型:

  1. Char(字符型):

    • fields.Char:用于存储短文本字符串,例如名称、标题等。
  2. Text(文本型):

    • fields.Text:用于存储长文本字符串,例如描述、备注等。
  3. Integer(整数型):

    • fields.Integer:用于存储整数值。
  4. Float(浮点型):

    • fields.Float:用于存储浮点数值,可以包含小数部分。
  5. Boolean(布尔型):

    • fields.Boolean:用于存储布尔值(True或False)。
  6. Date(日期型):

    • fields.Date:用于存储日期。
  7. Datetime(日期时间型):

    • fields.Datetime:用于存储日期和时间。
  8. Selection(选择型):

    • fields.Selection:用于提供预定义选项的下拉列表。
  9. Binary(二进制型):

    • fields.Binary:用于存储二进制数据,例如图像、文件等。
  10. Many2one(多对一关系型):

    • fields.Many2one:用于定义与其他模型的多对一关系。
  11. One2many(一对多关系型):

    • fields.One2many:用于定义与其他模型的一对多关系。
  12. Many2many(多对多关系型):

    • fields.Many2many:用于定义与其他模型的多对多关系。

这些字段类型可以通过Python代码中的fields模块来定义,并在模型类中使用。例如: 

from odoo import models, fields

class MyModel(models.Model):
    _name = 'my.model'

    name = fields.Char(string='Name')
    description = fields.Text(string='Description')
    age = fields.Integer(string='Age')
    amount = fields.Float(string='Amount')
    is_active = fields.Boolean(string='Is Active')
    date = fields.Date(string='Date')
    datetime = fields.Datetime(string='Date and Time')
    selection_field = fields.Selection([('option1', 'Option 1'), ('option2', 'Option 2')], string='Selection Field')
    binary_data = fields.Binary(string='Binary Data')
    related_model_id = fields.Many2one('related.model', string='Related Model')
    child_ids = fields.One2many('child.model', 'parent_id', string='Children')
    other_model_ids = fields.Many2many('other.model', 'model_other_rel', 'model_id', 'other_id', string='Other Models')

2、字段中可定义的参数 

  1. string:

    • 说明:用于在用户界面上显示字段的标签或标签。
    • 示例:string='Name'
  2. help:

    • 说明:提供有关字段用途或其他相关信息的帮助文本。
    • 示例:help='Enter the name of the record.'
  3. readonly:

    • 说明:如果设置为True,则将字段设置为只读,用户无法在界面上编辑该字段的值。
    • 示例:readonly=True
  4. required:

    • 说明:如果设置为True,则表示该字段在创建记录时是必需的,用户必须为其提供值。
    • 示例:required=True
  5. index:

    • 说明:如果设置为True,则在数据库中为该字段创建索引,以加速查询。
    • 示例:index=True
  6. compute:

    • 说明:指定一个计算方法,该方法在访问字段值时自动调用,根据其他字段的值计算该字段的值。
    • 示例:compute='_compute_field_value'
  7. inverse:

    • 说明:指定反向计算方法,该方法在尝试写入计算字段时自动调用。
    • 示例:inverse='_inverse_field_value'
  8. store:

    • 说明:如果设置为False,则表示计算字段不会存储在数据库中。默认情况下,计算字段存储在数据库中,以便可以在查询中使用。
    • 示例:store=True
  9. related:

    • 说明:指定与另一个模型的关联字段,允许在两个相关模型之间共享信息。
    • 示例:related='partner_id.name'
  10. default:

    • 说明:指定字段的默认值,在创建记录时将使用该值。
    • 示例:default='New Record'
  11. selection:

    • 说明:定义字段的预定义选项列表。用于fields.Selection字段类型。
    • 示例:selection=[('draft', 'Draft'), ('done', 'Done')]
  12. size:

    • 说明:指定字段的大小限制。用于fields.Charfields.Text字段类型。
    • 示例:size=100
  13. digits:

    • 说明:定义浮点字段的精度,包括整数部分和小数部分的位数。
    • 示例:digits=(10, 2)
  14. group_operator:

    • 说明:在一对多关系字段上使用,指定计算子记录的操作符,如sumavg等。
    • 示例:group_operator="sum"
  15. states: 
    • 说明:传入依赖state字段值的UI属性字典映射值
    • 示例:可用属性有readonly、required和invisible,例如states={'done′:[('readonly′,True)]}。
  16. copy
    • 说明copy=False让字段在使用ORM copy()方法复制记录时忽略该字段,除对多关联字 段默认不复制,其它字段值默认会被复制。
    • 示例:copy=False
  17. translate
    • 说明用于指示字段的翻译性质。如果设置为 True,表示字段的值是可翻译的;如果设置为 False,则表示字段的值不需要进行翻译。
    • 示例translate=True

这些参数可以根据字段的类型和具体需求进行组合和调整。

3、保留字段名

         

        一些内置API功能默认需要一些指定字段名,这些是保留字段名,应避免误用                      

保留字段如下:                          

  1.  Char类型的name或x_name:默认用作记录的显示名                            
  2. 布尔类型的active和x_active:允许我们关闭记录,让记录隐藏                          
  3.  Selection类型的state:表示记录生命周期的基本状态                          
  4.  多对一字段的parent_id:用于定义树状层级结构,在域表达式中启用child_of和parent_of运算符                            
  5. Char类型的parent_path:用在域表达式中优化child_of和parent_of运算符的使用                  
  6. Many2one类型的company_id:用于标识记录所属的公司 

 4、关联字段

 从关联记录中将值拷贝到模型自己的字段中。通常用于在表单中显示关联记录的字段。

 1、Many2one(多对一)

         Many2one 字段表示多个记录可以指向另一个模型中的一个记录。这种关系通常用于表示属于关系,例如,订单属于一个客户。

 例子:

from odoo import models, fields

class SaleOrder(models.Model):
    _name = 'sale.order'

    partner_id = fields.Many2one('res.partner', string='Customer')

 2、Many2many(多对多)

         Many2many 字段表示多个记录可以与另一个模型中的多个记录相关联。这种关系通常用于表示多对多的关系,例如,产品可以属于多个销售订单,而订单也可以包含多个产品。

 例子:

from odoo import models, fields

class SaleOrder(models.Model):
    _name = 'sale.order'

    order_lines = fields.Many2many('product.product', string='Order Lines')

3、 One2many(一对多)

         One2many 字段表示一个记录可以与另一个模型中的多个记录相关联。这种关系通常用于表示一对多的关系,例如,一个客户可以有多个销售订单。

 例子:

from odoo import models, fields

class ResPartner(models.Model):
    _name = 'res.partner'

    sale_orders = fields.One2many('sale.order', 'partner_id', string='Sale Orders')

        在这个例子中,ResPartner 模型有一个 One2many 字段 sale_orders,它引用了 sale.order 模型中的销售订单记录,关联字段是 partner_id

用法总结

  • Many2one 字段用于表示多个记录关联到另一个模型的一个记录。
  • Many2many 字段用于表示多个记录与另一个模型的多个记录相关联。
  • One2many 字段用于表示一个记录与另一个模型的多个记录相关联。
  • Many2oneMany2many 字段中,你可以使用 string 参数为字段指定一个用户友好的标签。

 关联字段的参数详解

relation/comodel

        说明:用于指定与当前字段关联的模型

        示例:

partner_id = fields.Many2one('res.partner', string='Partner')

 ondelete

        说明:用于指定在删除与当前字段关联的记录时的行为。该参数控制了数据库级别的外键约束的行为(关联记录删除时执行的操作)

        取值:

  • 'cascade':级联删除,表示删除主记录时同时删除关联的从记录。
  • 'set null':将关联字段的值设置为 NULL
  • 'restrict':阻止删除主记录,如果有关联记录存在。
  • 'no action':不执行任何操作,由数据库引擎处理。

        示例:

partner_id = fields.Many2one('res.partner', string='Partner', ondelete='set null')

 context(常用)

         context 参数是在调用 API 方法时传递的一个字典,用于传递上下文信息。这个字典中包含了一些上下文相关的键值对,可以影响方法的执行。context 参数通常用于传递一些额外的信息,如默认值、语言、用户上下文等。

以下是一些常见的用法和场景,其中 context 参数被广泛使用:

 默认值传递:

# 在创建记录时,传递默认值
new_record = model.create({'field_name': 'value'}, context={'default_field_name': 'default_value'})

语言设置:

# 在搜索记录时,传递语言上下文
records = model.search([('field_name', '=', 'value')], context={'lang': 'en_US'})

 用户上下文:

# 在执行某个方法时,传递用户上下文
result = model.method_name(context={'uid': 1, 'lang': 'en_US'})

视图上下文: 

# 在打开某个视图时,传递视图上下文
action = {
    'type': 'ir.actions.act_window',
    'name': 'Window Title',
    'view_mode': 'form',
    'res_model': 'your.model',
    'view_id': view_id,
    'target': 'new',
    'context': {'default_field_name': 'default_value'},
}

domain

          说明:该参数用于定义字段的域(Domain),即字段值的有效范围

          示例:

field_name = fields.Many2one('other.model', domain="[('field', '=', 'value')]")

delegate

          说明:delegate 参数用于将字段的属性委托给另一个模型或字段。这样,当前模型的字段将复制所指定模型或字段的属性。

          示例:

field_name = fields.Char(delegate=True)

auto_join

         说明:auto_join 参数用于指示 Odoo 是否自动连接到其他表以获取相关字段的信息。它在 Many2oneReference 字段中经常使用。

         示例:

field_name = fields.Many2one('other.model', auto_join=True)

 4、层级关联

        父子树状关联使用同一模型中多对一关联表示,其中每条记录指向其父级。反向的一对多关联表示记录的直接子级。

        Odoo 通过域表达式所带的child_of和parent_of运算符改良了对这些层级数据结构的支持。

         通过设置_parent_store=True模型属性等可加快等级树的查询速度。

层级关联的实现

在Odoo中,层级关联通过在同一个模型中引用相同模型的记录来实现。通常,使用parent_id字段来表示一个记录的父级。

 例子:

from odoo import models, fields

class ProductCategory(models.Model):
    _name = 'product.category'

    name = fields.Char(string='Category Name')
    parent_id = fields.Many2one('product.category', string='Parent Category', index=True)
    child_ids = fields.One2many('product.category', 'parent_id', string='Child Categories')

 在这个例子中,ProductCategory 模型表示产品分类,其中包含了一个 Many2one 字段 parent_id 用于引用自身模型中的父级分类。还有一个 One2many 字段 child_ids 用于引用该分类下的子分类。

层级关联的应用场景

        产品分类: 产品分类通常以树状结构进行组织,一个分类可以有多个子分类。

class ProductCategory(models.Model):
    _name = 'product.category'

    name = fields.Char(string='Category Name')
    parent_id = fields.Many2one('product.category', string='Parent Category', index=True)
    child_ids = fields.One2many('product.category', 'parent_id', string='Child Categories')

        组织结构: 公司的组织结构往往是层级关系,一个部门可以有多个子部门

class HrDepartment(models.Model):
    _name = 'hr.department'

    name = fields.Char(string='Department Name')
    parent_id = fields.Many2one('hr.department', string='Parent Department', index=True)
    child_ids = fields.One2many('hr.department', 'parent_id', string='Child Departments')

         地区信息: 地区信息常常以树状结构进行组织,一个地区可以包含多个子地区。

class ResCountry(models.Model):
    _name = 'res.country'

    name = fields.Char(string='Country Name')
    parent_id = fields.Many2one('res.country', string='Parent Country', index=True)
    child_ids = fields.One2many('res.country', 'parent_id', string='Child Countries')

5、引用字段的弹性关联(Reference字段

         

        普通关联字段只能指向一个固定的关联模型,但Reference字段类型不受这一限制,它支持 弹性关联,因此同一字段可指向多个目标模型。

 例子:

from odoo import models, fields

class ReferenceExample(models.Model):
    _name = 'reference.example'

    name = fields.Char(string='Name')
    reference = fields.Reference(
        [('res.partner', 'Partner'),
         ('product.product', 'Product'),
         ('res.user', 'User'),
        ],
        string='Reference'
    )

      该字段定义与Selection字段相似,但这里选择列表的内容为用于该字段的模型。在用户界 面中,用户会先选择列表中的模型,然后选择模型中的指定记录。

引用字段的应用场景

         通用关联: 当您希望一个字段能够引用多个不同模型的记录时,可以使用引用字段。例如,您可能有一个评论模型,评论可以关联到合作伙伴、产品或用户等不同类型的记录

class Comment(models.Model):
    _name = 'comment'

    text = fields.Text(string='Comment Text')
    referenced_record = fields.Reference(
        selection=[
            ('res.partner', 'Partner'),
            ('product.product', 'Product'),
            ('res.user', 'User'),
        ],
        string='Referenced Record'
    )

        动态关联: 当您的应用需要在运行时决定要关联的模型时,引用字段也很有用。例如,您可能有一个动态字段,根据用户的选择而关联到不同的模型。        

class DynamicReference(models.Model):
    _name = 'dynamic.reference'

    name = fields.Char(string='Name')
    dynamic_reference = fields.Reference(
        selection='_get_dynamic_models',
        string='Dynamic Reference'
    )

    def _get_dynamic_models(self):
        # 返回一个包含模型名称和标签的元组列表
        return [
            ('res.partner', 'Partner'),
            ('product.product', 'Product'),
            ('res.user', 'User'),
        ]

6、计算字段

       计算字段是一种特殊类型的字段,其值是通过在模型中定义的计算方法动态计算而得到的,而不是从数据库中存储的数据中读取的。计算字段的值在运行时根据计算方法而定,通常用于根据其他字段的值生成衍生信息。

        计算方法名的代码规范是在计算字段名前加上_compute_前缀。

        接收self记录集来进行运算,应当设置所有这些记录的 计算字段值。要对self记录集进行遍历来设置所有记录。

 以下是计算字段的一般定义和用法:

from odoo import models, fields, api

class MyModel(models.Model):
    _name = 'my.model'

    name = fields.Char(string='Name', required=True)
    value1 = fields.Float(string='Value 1')
    value2 = fields.Float(string='Value 2')

    # 定义计算字段
    computed_field = fields.Float(string='Computed Field', compute='_compute_computed_field', store=True)

    # 计算方法
    @api.depends('value1', 'value2')
    def _compute_computed_field(self):
        for record in self:
            record.computed_field = record.value1 + record.value2

         上述代码中,_compute_computed_field 方法定义了计算字段 computed_field 的计算逻辑。@api.depends 装饰器用于指定计算字段依赖的其他字段,这样当依赖的字段发生变化时,计算字段会自动重新计算。

关键要点解释:

  • compute='_compute_computed_field':这将计算字段与其计算方法关联起来。
  • store=True:该参数表示计算字段的值将被存储在数据库中,以便在查询时提高性能。如果不存储,计算字段的值将在每次查询时动态计算。

计算字段的主要应用场景包括:

  1. 衍生字段: 通过其他字段的计算得到的值,如总价、合计等。
  2. 格式化字段: 将其他字段的值格式化为特定的显示形式,如日期时间的格式化。
  3. 业务逻辑计算: 根据业务规则对字段进行计算,例如,计算订单的状态。

 计算字段的搜索,写入

         我们刚刚创建的计算字段可读取但不可搜索或写入。默认情况下计算字段是实时计算的,值 不存储在数据库中。这也是无法像普通字段那样进行搜索的原因。

         突破这种限制的一种方式是通过添加store = True属性让计算的值存储在数据库中。在任一 依赖发生变化时就会重新计算。因为值进行了存储,所以就可以像普通字段那样进行搜索, 无需搜索函数。

 计算字段还支持不进行存储的搜索及写入操作。可通过和计算方法一并实现特殊的方法来达成:

  • search方法来实现搜索逻辑

        当用户在视图中执行搜索操作时,计算字段可以参与搜索并返回满足条件的记录。以下是一个使用 search 方法的示例

from odoo import models, fields

class MyModel(models.Model):
    _name = 'my.model'

    name = fields.Char(string='Name', required=True)
    value1 = fields.Float(string='Value 1')
    value2 = fields.Float(string='Value 2')

    # 定义计算字段
    computed_field = fields.Float(string='Computed Field', compute='_compute_computed_field', store=True)

    # 计算方法
    def _compute_computed_field(self):
        for record in self:
            record.computed_field = record.value1 + record.value2

    # 搜索方法
    def _search_computed_field(self, operator, value):
        # 在计算字段上执行搜索逻辑
        return [('value1', operator, value - self.value2)]

    # 将搜索方法与计算字段关联
    computed_field = fields.Float(string='Computed Field', compute='_compute_computed_field', search='_search_computed_field', store=True)
  • inverse方法来实现写入逻辑

         计算字段通常是只读的,但通过定义 inverse 方法,您可以为计算字段提供一种写入的方式。以下是一个使用 inverse 方法的示例

from odoo import models, fields

class MyModel(models.Model):
    _name = 'my.model'

    name = fields.Char(string='Name', required=True)
    value1 = fields.Float(string='Value 1')
    value2 = fields.Float(string='Value 2')

    # 定义计算字段
    computed_field = fields.Float(string='Computed Field', compute='_compute_computed_field', inverse='_inverse_computed_field', store=True)

    # 计算方法
    def _compute_computed_field(self):
        for record in self:
            record.computed_field = record.value1 + record.value2

    # Inverse 方法
    def _inverse_computed_field(self):
        for record in self:
            # 在这里实现计算字段的写入逻辑
            record.value1 = record.computed_field - record.value2

关联字段 

        关联字段令关联模型中的字段在当前模型中可用,通过点号标记调用链访问。这让那些点号 标记符本无法使用之处可以访问关联字段,如UI表单视图。

        要创建关联字段,需要声明所需类型的字段,还要使用related属性,通过点号标记字段链来访问目标关联字段。

        默认关联字段是只读的,因而反向的写操作不可用。可通过设置readonly=False字段属性 来开启写操作。

        值得一提的是关联字段也可以像其它计算字段一样使用store=True将值存储在数据库中。

         关联字段的related属性用于创建一个与其他模型字段关联的字段。通过使用related属性,您可以在当前模型中创建一个字段,并且其值将自动与其他模型中指定的字段相关联。这通常用于在一个模型中显示另一个模型的某个字段的值,而无需在当前模型中存储该值。

from odoo import models, fields

class ModelA(models.Model):
    _name = 'model.a'

    name = fields.Char(string='Name')
    value = fields.Float(string='Value')

class ModelB(models.Model):
    _name = 'model.b'

    name = fields.Char(string='Name')
    
    # 创建关联字段 related_field,关联到 ModelA 模型的 value 字段
    related_field = fields.Float(string='Related Field', related='model_a_id.value', store=True)

    # 定义与 ModelA 模型的关联
    model_a_id = fields.Many2one('model.a', string='Model A')

         在上述代码中,ModelB模型中的related_field字段通过related属性与ModelA模型的value字段相关联。这意味着在ModelB的记录中,related_field的值将与model_a_id字段所关联的ModelA记录的value字段的值相同。

注意事项:

  • related属性中的路径 'model_a_id.value' 是一个点分隔的字段路径,指定了与当前模型关联的其他模型和字段。
  • 使用store=True参数可以将关联字段的值存储在数据库中,以便在数据库中进行查询。这对于在视图中进行排序、筛选或搜索是有帮助的。

这样,当您在ModelB的视图中查看或编辑记录时,related_field将显示与相关的ModelA记录关联的value字段的值。

  • 33
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Odoo是一种强大的开源企业资源计划(ERP)软件,许多开发者都在利用其灵活性和可定制性,为企业定制开发各种模块。而Odoo开发手册(PDF)就是一个详细的指南,它提供了所有关于Odoo开发的必要信息和指示。 这本Odoo开发手册PDF主要分为几个章节,第一章开始介绍了Odoo的背景和基本概念,包括Odoo架构、模块和功能等。第二章介绍了Odoo开发环境搭建,包括安装和配置的步骤。第三章开始详细介绍了Odoo模块开发的基本步骤,包括模块结构、文件类型和规范等。第四章讲解了Odoo模块间的关联和依赖,以及如何创建和管理它们之间的关系。第五章涵盖了Odoo的用户界面开发,包括视图、窗口和控件等的创建和使用。第六章介绍了Odoo的后端开发,包括数据模型、查询和操作等的实现。最后一章则是关于Odoo模块的测试和部署,包括如何编写和运行测试用例,以及如何发布和安装自己的模块。 这本Odoo开发手册PDF非常全面和详细,旨在帮助开发者理解和掌握Odoo开发的各个方面。它提供了实用的示例代码和步骤,使开发者能够按照自己的需求开发和定制Odoo模块。此外,该手册还包含了一些最佳实践和技巧,可以帮助开发者更有效和高效地进行Odoo开发。 总而言之,Odoo开发手册PDF是一本非常有用的资源,它可以帮助开发者深入了解和学习Odoo开发的各个方面。无论是初学者还是有经验的开发者,都可以从中获得宝贵的指导和参考。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dear.爬虫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值