odoo学习记录

创建模型应用: Python odoo-bin scaffold 模块名 myaddons

‘application’: True : 设置为应用
‘sequence’: 1 : 放置于第一个

一. 模型

1. 模型属性

attribute describe
_name odoo的内部标识符
_descirption 对用户友好的记录标题
_order=“name, price desc” 设置浏览记录和列表视图的默认数据
_rec_name 引用时用作记录描述,默认使用name字段
_table 通过该属性指定表明
_log_access=False 设置不自动创建审计追踪字段:create_uid,create_date,write_uid,write_date
_auto=False 用于设置不自动创建模型对应的数据表
_inhert 继承模型的属性字段

2.字段

2.1 字段类型
type describe
Char 单行文本,唯一位置参数是string字段标签
Text 多行文本,唯一位置参数是string字段标签
Selection(selection, string) 是一个下拉选择列表,选择位置参数是[(“value”, “title”)]
Html 文本字段,但有针对用户界面 HTML 内容展示的特殊处理。出于安全考虑,该字段会被清洗,但清洗行为可被重载。
Integer 仅需字段标题字符串参数
Float(string,digits) 第二个可选参数digits,该字段是一个指定字段精度的(x,y)元组,x是数字总长,y1是小数位
Monetary(string,currency_field) 与浮点字段类似,但带有货币的特殊处理.第二个参数currency_field用于存储使用货币,默认应传入curency_id字段
Date 和 Datetime 时期
Boolean 布尔类型
Binary 存储文件类二进制文件,只需一个字符串文本位置参数。
2.2 字段属性
attribute describe
readonly = True 使该字段默认不能在用户界面上编辑。
string 字段默认标签,用于在用户界面中使用。 除了选择和关系字段,它是第一个位置
default 为字段设置默认值。 它可以是一个静态值,例如一个字符串或一个可调用的引用,一个命名函数或一个匿名函数
(一个lambda表达式)。
help 提供显示给用户的工具提示的文本。
copy = False 在使用重复记录功能copy()ORM方法时,字段被忽略。默认情况下,非关系字段是可复制的。
group 允许将字段的访问和可见性限制为仅某些组。 它需要以逗号分隔的安全组的XML ID列表,例如groups =‘base.group_user,base.group_system’。
states 期望字典映射UI属性的值取决于状态字段的值。 例如:states = {‘done’:[(‘readonly’,True)]}。 可以使用的属性是readonly,required和invisible
translate 仅适用于Char,Text和Html字段,并使字段内容可翻译,为不同语言保存不同的值。
related 依赖字段 可以依赖 当前模型的
size 设置最大允许尺寸, 无特殊原因建议不要使用
trim 默认值为True,启动在网络客户端中自动去除周围的空格,可以设置为False取消
deprecated=True 在字段被使用时记录一条 warning 日志

3. 模型约束

3.1 在python当中校验
class Session(models.Model):
    ...
    @api.constrais('age')
    def _check_age(self):
        for record in self:
            if age > 20:
                raise ValidationError("年龄大于20")
"""
使用Constrains装饰器对某个age字段做了限制,当记录中的age字段的值发生变化时,_check_age就会被调用.便利所有记录(self 是一个recordset, 对应多条记录)做一些调节判断,不满足就抛出ValidationError异常
"""
# @api.constrains在字段发生改变时,进行检查,不会对原有数据进行检查
3.2 在数据库内部进行校验
_sql_constraints = [
    ('name_description_check',
    "CHECK(name != description)",
    "课程名与课程描述不能相同"),
    ("name_unique",
     "UNIQUE(name)",
     "课程名不能重复"
    )
]
# 如果表里已经存在冲突的数据,会导致sql约束更新不了
# 如果要删除已经存在的sql_onstraints, 先注释再从db里删除
# 否则会出现 raise ValidationError(int[0])TypeError:'integrtyError' object does not support indexing
3.3 重写copy 解决无法复制的问题

为了防止在字段设置了不能重复而无法复制的问题, 可以重写copy

@api.multi
def copy(self, default=None):
        default = dict(default or {})
       #统计数据库中已有多少个本纪录的副本
        copied_count = self.search_count(
            [('字段', '=like', u"Copy of {}%".format(self.字段))])
       #为副本中的字段值添加尾部修饰,维持唯一性
       #第一次复制:cpoy of 原字段值
        if not copied_count:
            new_字段 = u"Copy of {}".format(self.字段)
       #第n次复制:copy of 原字段值(次数)
        else:
            new_字段 = u"Copy of {} ({})".format(self.name, copied_count)
        #调用父类复制函数,并把新默认值传入
        default['字段名'] = new_字段
        return super(类名, self).copy(default)

4. ORM方法装饰器

4.1 @api.multi
import random
from odoo import models, fields

class ComputedModel(models.Model):
    _name = "test.computed"
    name = fields.Char(compute="_compute_name")
   
	@api.multi
    def _compute_name(self):
        for record in self:
            record.name = str(random.randint(1, 1e6))

当每次rec.name时,都调用方法来计算字段的值, self是一个rec集合(recordset),可以for循环出里面单个记录recordset还支持+号操作单个记录可以用.来访问字段

4.2 @api.depends
from odoo import models, fields, api
class ComputedModel(model.Model):
    _name = "test.computed"
    name = fields.Char(compute="_compute_name")
    value = fields.Integer()
    
    @api.depends("value")
    def _compute_name(self):
        for record in self:
            record.name = "Record with value %s" % self.value

通过@api.depends(‘value’) 当value值改变时会自动重新计算name,并显示在界面上

4.3 @api.onchange

onchange机制:不需要保存数据到数据库就可以实时更新用户界面上的显示

@api.onchage('监听的字段', '监听的字段')
def _onchage_受影响的字段(self):
    self.受影响的字段 = 根据监听字段计算出受影响的字段
    如果监听字段异常 返回错误
    return {
        'warning':{
            "title": "异常类型",
            "message": "具体异常信息",
        }
    }

5.env[‘modelname’]主要方法

  • search(): 搜索视图中调用
  • search_count(): 视图中计算记录时调用
  • name_search(): many2one字段搜索时调用
  • search_read(): many2one点开搜索更多时调用
  • read_group(): 搜索视图分组时调用

详细描述 - csdn: https://blog.csdn.net/sinat_23931991/article/details/86715272

6. self.env 默认值

打开shell 的命令 python odoo-bin shell

self.env  # 使用方法
self.env.cr or self._cr # 数据库指针
self.env.uid or self._uid  # 当前请求用户id
self.env.user  # 当前请求用户访问记录 可以访问self.env.user.name等
self.env.context or self._context # 当前上下文
self.env.ref(xml_id) # 通过xml_id访问某个记录xml_id对应ir_model_data的name字段
self.env[model_name]  # 返回某个model class对象 recordSet

二. 继承

1. 模型继承

1.1 类继承
_name = model_1
_inherit = model_1

__name 和 _inherit的模型名一致, 都为model_1,此时_name可以省略不写

类继承不会创建新的模型,能够直接修改模型定义,新的字段会在原表中添加,数据库中没有新的表生成

2.2 原型继承
_name = model_2
_inherit = model_1

_name 和 _inherit的模型名不同.相当于把模型1的属性(字段 方法等)copy了一份,重新创建了一个新的模型,新的表里有模型1的字段

2. 视图继承

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3XJvOwbI-1604395896100)(.\img\image-20201023083517108.png)]

2.1 position属性
inside(默认值) 在所选节点内添加内容,这一节点应该是或类的容器
after 在选定节点之后向父节点添加内容
before 在选定节点之前向父节点添加内容
replace 替换所选节点.若使用空元素则会删除该元素.odoo之后还允许用其他标记来包裹元素,通过在内容中使用$0来表示被替换的元素
attributes 修改匹配元素属性值。内容中应包含一个或多个value元素,如True,若不带内容,如会从所选元素中删除

提示:通过 position=”replace”可删除 XML 元素,但应避免这么做。这么做会破坏其它依赖所

删除节点、将其作为占位符添加元素的模块。一个替代方案是,让该元素不可见。

2.2 使用xpath选取节点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wtKbt48f-1604395896105)(.\img\image-20201023085908659.png)]

2.3 修改数据

数据加载元素实际是对 y 模型进行插入或更新操作。若不存在记录

x,则被创建,否则被更新/覆盖。其它模块中的记录可通过.全局标识符访问

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mUSOB6u2-1604395896107)(.\img\image-20201023090653780.png)]

点号是保留符号,用于分隔模块名和对象标识符,所以在标识符名中不要使用点号,而应使用下划

线字符。

2.4 其他模型继承机制

原型继承主要用于支持 mixin 类。mixin 是基于 models.Abstract 的抽象的模型(而不是

models.Model),它在数据库中没有实际的体现,而是提供功能供其它模型复用(混合 mixed in)。

Odoo 插件提供多种 mixin,最常的两种由 Discuss 应用(mail 模块)提供:

  • mail.thread 提供在许多文档表单下方或右侧的消息面板功能,以及消息和通知相关逻辑。

  • mail.activity.mixin 模型提供待办任务计划。

第一步需要添加依赖

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CY4DEt35-1604395896111)(.\img\image-20201023113120825.png)]

第二步需要在类当中继承

class Member(models.Model):
    ...
	_inherit = ['mail.thread', 'mail.activity.mixin']
    ...

第三步在form视图当中添加如下数据

<form>
    ...
    <div class="oe_chatter">
        <field name="message_follower_ids" widget="mail_followers"/>
        <field name="activity_ids" widget="mail_activity"/>
        <field name="message_ids" widget="mail_thread"/>
    div>
    ...
form>

最后结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GnKdSgZR-1604395896114)(.\img\image-20201023114059652.png)]

三. odoo中对数据的权限控制机制

Odoo对数据的访问权限管理有两种机制: 模型访问权限管理(access rule),记录规则管理(record rule),模型访问权限管理的细化.

1. 访问权限组定义

在模块的security目录下,新建groups.xml文件,在其中定义权限组


<odoo>
    <data noupdate="0">
        <record id="权限组id" model="ir.module.category">
            <field name="name">XXX权限组field>
            <field name="description">XXX模块权限设置field>
        record>
    data>
odoo>

该文件是data文件,需要在__ manifest __.xml 中配置,在创建数据库后就会进行解析,往ir.module.category模型插入相应的记录,从而创建出对应的权限组.

2. 模型的权限访问控制

模型权限访问管理: 模型级的权限控制,该模型的所有记录,对于群组内用户(如果无定义,则对所有用户)的读写改删权限控制.

id,name,model_id,group_id,perm_read,perm_write,perm_create,perm_unlink

分别对应

id:记录的外部表示符(也称为XML ID)在我们的模块中应该是唯一
name: 描述标题.官方模块通常使用模块名称和组的圆点分隔符的字符串.如: todo.task.user
model_id: 模型的外部标识符.todo.task对应的标识符是model_todo_task
group_id:权限组,通过.xml文件.最重要一点是提供定义它的模块名前缀.必比如员工组,它的标识符为base.group_user.
perm_xx: 字段标记授予 读,写,创建,删除,权限.

最后,将模块的权限控制文件添加到 __ manifest __ 文件的data中加载

3. 记录访问控制

​ 记录控制: 记录级别的权限控制,可以为某模型的记录定义权限条件,对于某群组中(如果无指定,则指定所有用户)符合过滤条线的用户,赋予模型记录的读写改删权限.

​ 基于记录的权限可以控制指定模型的实例对象(数据记录)的访问权限

​ 记录规则的定义模型是ir.rule

​ 记录规则控制,我们需要提供一个独特的名称,还需要操作符和规则过滤器组成的模型以达到访问限制,在Odoo中,郭规则过滤器通常是多个元组组成的列表.

​ 规则适用于某些特定的访问组.如果它没有访问组,这种特殊情况,被认为思全局(global字段将自动设置为True).全局规则是不同的,以为他们实施了限制,不会被全局规则重写

  1. 在security目录下新建 模块名security.xml文件

  2. 在其中添加以下内容:


   <odoo>    
           <record id="模块名_对象_rule" model="ir.rule"> //为某对象添加记录规则
               <field name="name">规则名field>
               <field name="model_id" ref="model_模块名"/>
               //记录过滤表达式:符合该表达式的记录才能被访问
               <field name="domain_force">[('字段名','操作符',值)]field> 			
               //访问组id在第一步创建时指定,用于指定本规则作用于哪些组
               <field name="groups" eval="[(值,ref('访问组id'))]"/> 
               <field name="perm_read" eval="0/1"/>
               <field name="perm_write" eval="0/1"/>
               <field name="perm_create" eval="0/1"/>
               <field name="perm_unlink" eval="0/1" />
record> odoo>
  1. 添加到__ manifest_ __ 中

四. 业务逻辑

1. 创建向导

1.1 向导模型

创建临时模型 继承 TransientModel类

字段 One2many 关联不能在临时模型中使用. 代替方案是 Many2many关联

1.2 向导菜单

向导表单视图与普通模型相同, 只是有两个特定元素:

  • 可使用
    元素代替操作按钮
  • special=“cancel” 按钮用于终端向导,不执行任何操作
...
<field name="arch" type="xml">
    <form>
 		<group>
			<field name="message_subject" />
 			<field name="message_body" />
            <field name="checkout_ids" />
 		group>
 	<footer>
 		<button type="object"
 				name="button_send"
 			  	string="Send Message" />
 		<button special="cancel"
 				string="Cancel"
 				class="btn-secondary" />
    footer>
	form>
field>
...
<act_window id="action_checkout_message"
 			name="Send Messages"
 			src_model="library.checkout"
			res_model="library.checkout.massmessage"
 			view_type="form"
 			view_mode="form"
 			target="new"
 			multi="True"
/>

七. xml标签属性

属性 详情
nolable 是否显示string定义的标签名
readonly=“1” 只读
invisible = “1” 不显示到前端
context ‘default_子表字段’:active_id 一对多字段的显示tree视图, 可以自动选择当前字段
default_focus=“1” 该字段是否获得默认焦点
placeholder=“xxx” Char字段类型 指定默认值
domain 在关联字段中过滤对象
horizontal=“true” 在Selection字段中 横排显示单选按钮
options 详情
‘size’:[90,90] 调整大小
‘no_create’:‘1’ 不能添加新数据
‘no_open’: “1” 不打开外部链接

八. button按钮的属性

属性 描述
string 定义按钮显示文本
type 执行的操作类型
name 操作的标识符
class 应用css样式的可选属性,与HTML相同

九.QWeb

1. 声明模板

元素 作用声明QWeb模板

QWeb的属性

属性 描述
t-foreach 用于循环遍历每个项目由控制器的http.request.render()调用提供
t-as 循环出的单个
t-field 负责记录呈现的内容
用于数值条件

打印报表

使用OCA当中的报表引擎

https://github.com/OCA/reporting-engine/tree/12.0/report_py3o

安装之后,在本模块继承Py3o模块,安装相应的插件, 通过otd模板报表生成报表, 具体还需要安装libreOffice 在Windows当中还需要添加path (添加path后 可以在设置当中 打开用户 页面 打印报表 如果成功,配置就配置成功)

        <record id="dadian_u8_odt_record01_report" model="ir.actions.report">
            <field name="name">名字,生成后也叫这个field>
            
            <field name="model">dadian_u8.rd_record01field>
            
            <field name="report_name">py3o_采购_infofield>
            <field name="report_type">py3ofield>
             
            <field name="py3o_filetype">odtfield>
            
            <field name="module">dadian_u8field>
            
            <field name="binding_model_id" ref="dadian_u8.model_dadian_u8_rd_record01"/>
            
            <field name="py3o_template_fallback">reports/rd_record01_report.odtfield>
        record>

jinjia2模板语法

          
            odt
            
            dadian_u8
            
            
            
            reports/rd_record01_report.odt
        

jinjia2模板语法

链接: https://blog.csdn.net/qq_42672770/article/details/81007974

你可能感兴趣的:(odoo)