odoo基础知识1

  模块 ODOO中的Related字段及Computed字段原理

  Related 字段属性在数据库中是没有存储的,均是每次调用此字段时,通过函数计算出来。 所以,若想要让其他函数引用此 related 字段,必须添加 store = True 属性(存储字段的优点是,对该字段的搜索是由数据库本身完成的。)。 通过引用字段获取值来作为本字段的值
Inverse反参数的使用非常简单。通常,计算字段是只读的,因为它从记录集即时计算值。如果您需要在 计算字段上进行手动输入,可以通过给出反函数来完成。因此,当字段被写入/创建时,它会触发对修饰函数的调用。它反转计算并设置相关字段。
Invserse 通俗点讲的话,他是 Compute 的相反设置.我们在 field 中设置了它对应的 Compute 计算方法,那么这个字段就变成了只读的,这时候我们可以设置 inverse,来达到为该字段赋值的目的。设置了 inverse 这个,字段就可以在前端直接编辑,赋值就是通过这个 inverse 设置的方法。
  upper = fields.Char(compute='_compute_upper',
  inverse='_inverse_upper', search='_search_upper')
  @api.depends('employee_id')
  def _compute_upper(self):
    for rec in self:
      rec.upper = rec.employee_name.upper() if rec.employee_name else False
  def _inverse_upper(self):
    for rec in self:
      rec.employee_name = rec.upper.lower() if rec.upper else False
 
  Search默认情况下,计算字段不存储到数据库中,而是动态计算。添加属性“store=true”将在数据库 中存储字段值。
因此,不能正常搜索未存储在数据库中的计算字段,要启用搜索,必须显式定义搜索函数。这可以通过在计算字段中添加“搜索”参数来实现。如果我们添加一个方法来搜索计算字段,那么在 对模型进行实际搜索之前,在处理域时会调用该方法。
  standard_price = fields.Float(
  'Cost', compute='_compute_standard_price', inverse='_set_standard_price', search ='_search_standard_price', digits=dp.get_precision('Product Price'),     groups="base.group_user",
)
def _search_standard_price(self, operator, value):
  products = self.env['product.product'].search([('standard_price', operator, value)], limit=None)
  return [('id', 'in', products.mapped('product_tmpl_id').ids)]
 
  1. 常用装饰器、
  • 处理记录集,在这种情况下,应该使用@api.multi装饰器,并且可以使用self参数以方便地获取记录集
  • 在Odoo中,对于类型这种静态方法,可使用@api.model装饰器,这种方法的self参数是一个对象的引用而非一个记录集。但使用@api.model装饰的方法不能用于用户界面的按扭
  • @api.depends(字段1,字段2,…)装饰器用于计算字段(computed field),可以用于标示需要被触发的计算。使用此装饰器应该注意计算字段(computed field)必须被赋值,否则会就报错 ,计算字段的值通常取决于所在记录行的其它字段的值
  • ·@api.constraints(字段1,字段2,…)用于评估和检查,当参数字段的值发生变化时,会进行检查,如果检查规则不通过,则字段值不会发生变化,并且会报出一个异常。(用于校验,弹框报错)
  • @api.onchange(字段1,字段2,…)用于系统在与用户进行交互时自动更新相关联的字段 需要注意的是,这个方法的具体名字与方法的触发没有直接关联性,Odoo主要是通过方法的装饰器来找到方法的。在onchange方法中,参数self代表的是包含了form所有可编辑字段的单一记录
  • 上述几个装饰器,除了onchange可选地返回一个字典之外,其他的都不需要返回任何值。onchange返回的数据往往也是返回给UI的一些提示信息。
  1. ORM内置方法
  • ·.create(values)方法可以创建新记录并且可以通过return方法返回。
  • ·.write(values)方法可用于更新记录,并且不需要返回值。
  • ·.unlink()方法可从数据库删除记录,不需要返回值。
  • 上述方法中的values参数是字典类型,执行方法时可将字段与字段值进行对照来匹配。一般情况下,我们会集成这些方法并且增加一些自己需要的业务逻辑处理,当这些方法被触发时,我们新增的逻辑将会得到执行。新增的代码既可以在继承的代码之前,也可以在继承的代码之后。
使用RPC的网页端方法
  • read([fields])与browse方法类似,但是read方法返回的记录仅包括参数中包含的字段。返回数据的每一行记录都是字典的形式
  • search_read([domain],[fields],offset=0,limit=None,order=None)方法可以在结果记录集上面再次执行查找的操作
数据导入导出方法
  • load([fields],[data])可用于从CSV文件导入数据。第一个参数列出需要的字段,列的名称直接使用CSV文件第一行的名称。而第二个参数则可以列出需要的记录,每一行记录都可以由其各列的数据组成
  • export_data([fields],raw_data=False)用于从页面端导出数据。这种方法将返回一个字典,字段的数值键包含一个行列表
下列方法主要用于UI发起的交互
  • name_get()方法可返回(ID,name)元组组成的列表,每个元组代表一行记录,该方法可默认用于获取display_name
  • ·name_search(name='',args=None,operator='ilike',limit=100)可返回(ID,name)元组组成的列表,显示名称将会与参数name的文本进行匹配进而定位记录,一般应用会根据在UI上输入的一个字段去获取该记录的其他字段
  • name_create(name)可用于根据名称快速创建一行新记录,该记录在创建时仅具有名称字段,使用的时候可以继承扩展此方法,用于在创建记录时为一些字段设置默认值。
  • ·default_get([fields])可返回一个具有待创建新记录默认值的字典 比如根据当前用户或者会话上下文的变量 ,
其他方法
  可使用search_count()方法查询记录的数量,因为要查询所有记录数,所以参数传了个空列表。
我们可以做在odoo预置的方法 fields_get中进行处理,fields_get方法在每次进入tree视图的时候回执行,实现格式如下:
对返回值的赋值 [key]['参数']=值
  • @api.model
  • def fields_get(self, allfields=None, attributes=None):
    •   res = super(OkrManageLine, self).fields_get(allfields, attributes)
    •   for key, value in res.items():
      •     if key == 'create_date': #res={"create_date":value1,'write_date':value2}
        •       res[key]['string'] = '创建时间'
        •       elif key == 'write_date':
        •       res[key]['string'] = '最后更新时间'
    •   return res
  • 调用父类fields_get的返回值是议程字典,我们可以通过判断字段的名称对其在筛选和分组中的显示标签进行调整
  • 在筛选和分组中对一些字段进行隐藏实现格式如下:
  • @api.model
  • def fields_get(self, allfields=None, attributes=None):
  • # 过滤掉筛选中不显示项
    •   res = super(SupplierInvoiceRecordPivot, self).fields_get(allfields, attributes)
    •   filter_field = ['create_uid', 'write_date', 'create_date', 'write_uid', 'uid']
    •   for key, value in res.items():
      •     if key in filter_field:
        •       res[key]['searchable'] = False
        •       res[key]['sortable'] = False
    •   return res
  • res[key][‘searchable’] = False 设置字段 key 在筛选中不可见
  • res[key][‘sortable’] = False 设置字段key在分组中不可见
shell命令 odoo-bin shell -d 数据库
服务器环境
  • self引用的多个记录集,既有环境信息的记录集、用户浏览数据的记录集,又有上下文(context)信息等
  • 使用self.env来查看当前用户运行的环境信息
·env.cr是当前的数据库光标。
·env.user是当前用户的记录。
·env.uid是会话中用cd 户的ID,相当于使用env.user.id。
·env.context是会话上下文的不可变字典
env.with_context(dictionary)可使用参数中的字段数据代替原来的上下文信息。 改变上下文信息
·env.sudo(user)通过参数指定的用户返回所属用户的环境,在这个环境内执行相关动作就可以越过安全规则的限制,无user 默认adm
环境还提供了对所有已安装模块的可用注册表的访问。比如,self.env['res.partner']可返回合作伙伴模型的引用,还可以使用search()或browse()对记录集进行检索。
  • 事务和底层SQL
对于事务的相关操作,可以通过数据库光标self.env.cr来完成,
其用法包括如下几种。
·self.env.cr.commit()用于提交本次事务,完成后数据的更新操作即完成。
·self.env.cr.savepoint()设置一个保存点,在回滚时使用,回滚将截至最近的保存点。
·self.env.cr.rollback()取消当前的更新操作,回滚到上次提交时的点。
.在进行数据库层面的直接更新操作时,一定要使用.self.env.cr.commit(),否则更新不会起作用。
.如果使用的是SELECT查询,那么应该获取记录。fetchall()函数检索所有的行
.也正因为如此,在使用原始的DML时,应该在完成后使用self.env.invalidate_all()清空这些缓存。
Context
  • 在前端中context可以将信息从一个视图传递到下一个。比如将上一个窗体的记录ID,在按钮点击动作完成后传递到下一个窗体。在服务器端,记录集的字段值可以依赖context提供的本地设置 context也可以为服务器端提供一些信号信息,比如将关键字active_test的值设置为False时,ORM的search方法在执行时就不会过滤inactive状态的记录。
·active_model:记录视图模型的技术名称。
·active_id:如果是表单视图则记录活跃状态的记录ID,如果是列表视图则记录第一条记录的ID。
·active_ids:列表视图所有活跃状态的记录ID,如果是表单视图则只记录一个元素。
  • context在客户端可以用来设置目标视图的默认值或激活默认筛选器,可以使用以default_或default_search_开头的关键字来完成这种设置
例子: {'default_user_id':uid}:将当前用户设置为user_id字段的默认值。
·{'default_search_filter_my_bugs':1}:将filter_my_bugs设置为默认过滤器
Domain 形如('<field_name>','',)
  • domain表达式的就较为简单了,可以是以下几种
·通常的比较符号:<、>、<=、>=、=、!=。
·=like:匹配模式,下划线(_)匹配任意一位的字符,百分号(%)匹配任意的字符串
·like:匹配%value%模式 也可以用not like和not ilike
·child of:用于在层级关系中发现子节点的值,当然必须是模型被设置成层级模型时才支持。
·in和not in:用于检测给定的列表中是否包含或不包含,所以该值也应该是列表值。
当然,也可以使用显式的逻辑运算符,比如常用的&(AND)、|(OR),使用的时候先写逻辑运算符,它们会在后面的两个元组上起作用
查询模型
对于self,我们只能访问该方法的记录集。但是self.env环境引用允许我们访问任何其他模型
  • search()方法可获取一个domain表达式,并返回一个记录集记录匹配这些条件 search()方法可获取一个domain表达式,并返回一个记录集记录匹配这些条件
默认情况下只有active=True的记录才会被考虑
这里有一些可选的关键字参数,
·order可用作ORDER BY条件的数据库查询字符串。这通常是一个以逗号分隔的字段名列表。
·limit用于设置要检索的最大记录数量。
·offset用于忽略第一批n个结果;
其可以用于limit以查询一段时间内的记录。
  • 为此,可以使用search_count()来返回记录计数而不是记录集
写记录集 create()、write()和unlink()。
  • copy()可复制一个已有的记录;并且可带有一个可选的参数和一个带有值的字典 如果模型中的字段属性copy设置为False,则不会被复制
日期和时间
  • ·fields.Date.today()返回当前日期的字符串格式
  • ·fields.Datetime.now()返回一个带有当前datetime的字符串
  • fields.Date.context_today(record,timestamp=None)返回一个在会话的上下文中使用的当前日期
  • 为了方便格式之间的转换,fields.Date和fields.Datetime提供了如下功能。
·from_string(value)将字符串转换为日期或datetime对象。
·to_string(value)转换一个date或datetime对象为字符串,这也是服务器所期望的格式
操作记录集
  • 如果x是一个单例记录集,而the_recordset是一个包含许多记录的记录集,那么可以使用它进行如下操作:
·x in the_recordset
·x not in the_recordset
·recordset.ids返回以元素IDs记录集列表
  • ·recordset.filtered(func)返回一个经过过滤的记录集。
·recordset.mapped(func)返回一个映射值的列表。
·recordset.sorted(func)返回一个有序的记录集。
0
  • 如何对记录集进行操作
·rs1|rs2是设置union的操作,结果是两个记录集所有的元素。
·rs1+rs2是设置addition的操作,结果是两个记录集作为一体的元素,它可能会导致重复记录。
·rs1&rs2是设置intersection的操作,结果只是两个记录集相同的元素。交集
·rs1–rs2是设置difference的操作,结果是rs1元素不在rs2记录集中的元素也可以使用切片表示法, 差集
例如,如下这些例子。
·rs[0]和rs[-1]可分别检索第一个元素和最后一个元素。
·rs[1:]的结果是复制没有第一个元素的记录集。这将生成与rs–rs[0]相同的记录,但它会保存原来的顺序
如下:·self.write([(4,bug1.id,None)])添加task1记录。
·self.write([(3,bug1.id,None)])从记录集删除task1。
·self.write([(3,self.bug_ids[-1].id,False)])删除最后一条记录。
模型包含如下三种关系字段:多对一、一对多和多对多。这些字段类型以记录集作为值。
  • 在多对一的情况下,值可以是单例或空记录集。在这两种情况下,我们都可以直接访问它们的字段值。
  • 一对多字段,它们的值也可以用记录集来进行分配,这里允许一个任意大小的记录集
在使用create()或write()方法时,可在其中指定使用字典的值,关系字段不能被分配给记录集值,此时应该使用相应的ID或IDs列表。
例如,替换self.write({'user_id':self.env.user})时,我们应该使用self.write({'user_id':self.env.user.id})

posted on   nn_ning  阅读(39)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示