创建模型应用: Python odoo-bin scaffold 模块名 myaddons
‘application’: True : 设置为应用
‘sequence’: 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 | 继承模型的属性字段 |
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 | 存储文件类二进制文件,只需一个字符串文本位置参数。 |
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 日志 |
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在字段发生改变时,进行检查,不会对原有数据进行检查
_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
为了防止在字段设置了不能重复而无法复制的问题, 可以重写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)
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还支持+号操作单个记录可以用.来访问字段
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,并显示在界面上
onchange机制:不需要保存数据到数据库就可以实时更新用户界面上的显示
@api.onchage('监听的字段', '监听的字段')
def _onchage_受影响的字段(self):
self.受影响的字段 = 根据监听字段计算出受影响的字段
如果监听字段异常 返回错误
return {
'warning':{
"title": "异常类型",
"message": "具体异常信息",
}
}
详细描述 - csdn: https://blog.csdn.net/sinat_23931991/article/details/86715272
打开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
_name = model_1
_inherit = model_1
__name 和 _inherit的模型名一致, 都为model_1,此时_name可以省略不写
类继承不会创建新的模型,能够直接修改模型定义,新的字段会在原表中添加,数据库中没有新的表生成
_name = model_2
_inherit = model_1
_name 和 _inherit的模型名不同.相当于把模型1的属性(字段 方法等)copy了一份,重新创建了一个新的模型,新的表里有模型1的字段
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3XJvOwbI-1604395896100)(.\img\image-20201023083517108.png)]
inside(默认值) | 在所选节点内添加内容,这一节点应该是或类的容器 |
---|---|
after | 在选定节点之后向父节点添加内容 |
before | 在选定节点之前向父节点添加内容 |
replace | 替换所选节点.若使用空元素则会删除该元素.odoo之后还允许用其他标记来包裹元素,通过在内容中使用$0来表示被替换的元素 |
attributes | 修改匹配元素属性值。内容中应包含一个或多个value元素,如True,若不带内容,如会从所选元素中删除 |
提示:通过 position=”replace”可删除 XML 元素,但应避免这么做。这么做会破坏其它依赖所
删除节点、将其作为占位符添加元素的模块。一个替代方案是,让该元素不可见。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wtKbt48f-1604395896105)(.\img\image-20201023085908659.png)]
数据加载元素实际是对 y 模型进行插入或更新操作。若不存在记录
x,则被创建,否则被更新/覆盖。其它模块中的记录可通过.全局标识符访问
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mUSOB6u2-1604395896107)(.\img\image-20201023090653780.png)]
点号是保留符号,用于分隔模块名和对象标识符,所以在标识符名中不要使用点号,而应使用下划
线字符。
原型继承主要用于支持 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对数据的访问权限管理有两种机制: 模型访问权限管理(access rule),记录规则管理(record rule),模型访问权限管理的细化.
在模块的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模型插入相应的记录,从而创建出对应的权限组.
模型权限访问管理: 模型级的权限控制,该模型的所有记录,对于群组内用户(如果无定义,则对所有用户)的读写改删权限控制.
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中加载
记录控制: 记录级别的权限控制,可以为某模型的记录定义权限条件,对于某群组中(如果无指定,则指定所有用户)符合过滤条线的用户,赋予模型记录的读写改删权限.
基于记录的权限可以控制指定模型的实例对象(数据记录)的访问权限
记录规则的定义模型是ir.rule
记录规则控制,我们需要提供一个独特的名称,还需要操作符和规则过滤器组成的模型以达到访问限制,在Odoo中,郭规则过滤器通常是多个元组组成的列表.
规则适用于某些特定的访问组.如果它没有访问组,这种特殊情况,被认为思全局(global字段将自动设置为True).全局规则是不同的,以为他们实施了限制,不会被全局规则重写
在security目录下新建 模块名security.xml文件
在其中添加以下内容:
<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>
创建临时模型 继承 TransientModel类
字段 One2many 关联不能在临时模型中使用. 代替方案是 Many2many关联
向导表单视图与普通模型相同, 只是有两个特定元素:
...
<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"
/>
属性 | 详情 |
---|---|
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” | 不打开外部链接 |
属性 | 描述 |
---|---|
string | 定义按钮显示文本 |
type | 执行的操作类型 |
name | 操作的标识符 |
class | 应用css样式的可选属性,与HTML相同 |
元素 作用声明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>
odt
dadian_u8
reports/rd_record01_report.odt
链接: https://blog.csdn.net/qq_42672770/article/details/81007974