目录
1、基本字段类型
在Odoo中,基本字段类型是用于模型(Model)的字段,它们用于存储各种类型的数据。以下是Odoo中常见的基本字段类型:
-
Char(字符型):
fields.Char
:用于存储短文本字符串,例如名称、标题等。
-
Text(文本型):
fields.Text
:用于存储长文本字符串,例如描述、备注等。
-
Integer(整数型):
fields.Integer
:用于存储整数值。
-
Float(浮点型):
fields.Float
:用于存储浮点数值,可以包含小数部分。
-
Boolean(布尔型):
fields.Boolean
:用于存储布尔值(True或False)。
-
Date(日期型):
fields.Date
:用于存储日期。
-
Datetime(日期时间型):
fields.Datetime
:用于存储日期和时间。
-
Selection(选择型):
fields.Selection
:用于提供预定义选项的下拉列表。
-
Binary(二进制型):
fields.Binary
:用于存储二进制数据,例如图像、文件等。
-
Many2one(多对一关系型):
fields.Many2one
:用于定义与其他模型的多对一关系。
-
One2many(一对多关系型):
fields.One2many
:用于定义与其他模型的一对多关系。
-
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、字段中可定义的参数
-
string:
- 说明:用于在用户界面上显示字段的标签或标签。
- 示例:
string='Name'
-
help:
- 说明:提供有关字段用途或其他相关信息的帮助文本。
- 示例:
help='Enter the name of the record.'
-
readonly:
- 说明:如果设置为
True
,则将字段设置为只读,用户无法在界面上编辑该字段的值。 - 示例:
readonly=True
- 说明:如果设置为
-
required:
- 说明:如果设置为
True
,则表示该字段在创建记录时是必需的,用户必须为其提供值。 - 示例:
required=True
- 说明:如果设置为
-
index:
- 说明:如果设置为
True
,则在数据库中为该字段创建索引,以加速查询。 - 示例:
index=True
- 说明:如果设置为
-
compute:
- 说明:指定一个计算方法,该方法在访问字段值时自动调用,根据其他字段的值计算该字段的值。
- 示例:
compute='_compute_field_value'
-
inverse:
- 说明:指定反向计算方法,该方法在尝试写入计算字段时自动调用。
- 示例:
inverse='_inverse_field_value'
-
store:
- 说明:如果设置为
False
,则表示计算字段不会存储在数据库中。默认情况下,计算字段存储在数据库中,以便可以在查询中使用。 - 示例:
store=True
- 说明:如果设置为
-
related:
- 说明:指定与另一个模型的关联字段,允许在两个相关模型之间共享信息。
- 示例:
related='partner_id.name'
-
default:
- 说明:指定字段的默认值,在创建记录时将使用该值。
- 示例:
default='New Record'
-
selection:
- 说明:定义字段的预定义选项列表。用于
fields.Selection
字段类型。 - 示例:
selection=[('draft', 'Draft'), ('done', 'Done')]
- 说明:定义字段的预定义选项列表。用于
-
size:
- 说明:指定字段的大小限制。用于
fields.Char
和fields.Text
字段类型。 - 示例:
size=100
- 说明:指定字段的大小限制。用于
-
digits:
- 说明:定义浮点字段的精度,包括整数部分和小数部分的位数。
- 示例:
digits=(10, 2)
-
group_operator:
- 说明:在一对多关系字段上使用,指定计算子记录的操作符,如
sum
、avg
等。 - 示例:
group_operator="sum"
- 说明:在一对多关系字段上使用,指定计算子记录的操作符,如
states:
说明:传入依赖state字段值的UI属性字典映射值
- 示例:可用属性有readonly、required和invisible,例如states={'done′:[('readonly′,True)]}。
- copy
- 说明:copy=False让字段在使用ORM copy()方法复制记录时忽略该字段,除对多关联字 段默认不复制,其它字段值默认会被复制。
- 示例:copy=False
- translate
- 说明:用于指示字段的翻译性质。如果设置为
True
,表示字段的值是可翻译的;如果设置为False
,则表示字段的值不需要进行翻译。 - 示例:translate=True
- 说明:用于指示字段的翻译性质。如果设置为
这些参数可以根据字段的类型和具体需求进行组合和调整。
3、保留字段名
一些内置API功能默认需要一些指定字段名,这些是保留字段名,应避免误用
保留字段如下:
- Char类型的name或x_name:默认用作记录的显示名
- 布尔类型的active和x_active:允许我们关闭记录,让记录隐藏
- Selection类型的state:表示记录生命周期的基本状态
- 多对一字段的parent_id:用于定义树状层级结构,在域表达式中启用child_of和parent_of运算符
- Char类型的parent_path:用在域表达式中优化child_of和parent_of运算符的使用
- 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
字段用于表示一个记录与另一个模型的多个记录相关联。- 在
Many2one
和Many2many
字段中,你可以使用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 是否自动连接到其他表以获取相关字段的信息。它在 Many2one
或 Reference
字段中经常使用。
示例:
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
:该参数表示计算字段的值将被存储在数据库中,以便在查询时提高性能。如果不存储,计算字段的值将在每次查询时动态计算。
计算字段的主要应用场景包括:
- 衍生字段: 通过其他字段的计算得到的值,如总价、合计等。
- 格式化字段: 将其他字段的值格式化为特定的显示形式,如日期时间的格式化。
- 业务逻辑计算: 根据业务规则对字段进行计算,例如,计算订单的状态。
计算字段的搜索,写入
我们刚刚创建的计算字段可读取但不可搜索或写入。默认情况下计算字段是实时计算的,值 不存储在数据库中。这也是无法像普通字段那样进行搜索的原因。
突破这种限制的一种方式是通过添加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
字段的值。