视频教程地址:http://www.iqiyi.com/playlist514968002.html
odoo中字段的定义和含义
# _*_ coding:utf-8 _*_
# author: zhy
import uuid
from itertools import groupby
from datetime import datetime, timedelta
from werkzeug.urls import url_encode
from odoo import api, fields, models, _
from odoo.exceptions import UserError, AccessError
from odoo.osv import expression
from odoo.tools import float_is_zero, float_compare, DEFAULT_SERVER_DATETIME_FORMAT
from odoo.tools.misc import formatLang
class zhy_sale(models.Model):
_name = "zhy.sale"
_description = u"销售订单"
# 隐藏创建人创建日期字段
_log_access = False
name = fields.Char(string=u'单据编号', default=lambda self: 'New')
active = fields.Boolean(default=True, string=u'是否归档', track_visibility='onchange')
sequence = fields.Integer(string=u'排序', default=10)
# require=True表示的是必填
price_unit = fields.Float(string=u'单价', require=True, default=0.0, digits=(10,2))
note = fields.Text(string=u'备注', track_visibility='onchange')
content = fields.Html(string=u'正文', strip_style=True)
# track_visibility='onchange'表示的是会在更改信息的时候,message会提示相关的更改信息
# 这个要和下面message社交中的应用联合使用
delivary_date = fields.Date(string=u'发货日期', track_visibility='onchange')
# default=fields.Datetime.now表示的是获取当前日期
date_order = fields.Datetime(string=u'单据日期', required=True, readonly=True, index=True, copy=False, default=fields.Datetime.now)
priority = fields.Selection([
('0', '低'),
('1', '正常'),
('2', '高'),
], default='0', index=True, string=u'优先级')
# res.users表示的是关联的当前用户的表, default表示的是创建的时候默认成当前用户
# lambda self: self.env.user中user表示的是当前的用户, 如果是想关联其他的用户,可以找个这个用户的id,然后再设置中 default=id即可
# xml中(ir.actions.act_window)定义{"default_user_id":7}
user_id = fields.Many2one('res.users', string=u'负责人', index=True, track_visibility='onchange',
default=lambda self: self.env.user)
# 关联字段,一对多的关联 第一个位置表示的是关联的表的名称,第二个字段是表中的字段名称 auto_join表示是否在搜索字段时,生成连接
order_line = fields.One2many('zhy.sale.line', 'order_id', string=u'订单明细行', copy=True, auto_join=True)
# 多对多的关系 a_b_rel a表示的是表名,b表示的是关联字段的表名 a_id b_id可以自己定义 一般是关联表的名称,分别表示的是关联表的名称
# some_ids = fields.Many2many('models', 'a_b_rel', 'a_id', 'b_id')
# res.users表和zhy.sale关联的数据放在zhy_sale_res_users_rel中
users_ids = fields.Many2many('res.users', 'zhy_sale_res_users_rel', 'sale_id', 'user_id', string=u'业务员')
@api.model
def _select_objects(self):
records = self.env['ir.model'].search([])
return [(record.model, record.name) for record in records] + [('','')]
# 可以关联所有的字段
id_object = fields.Reference(string=u'关联', selection='_select_objects')
class zhy_sale_line(models.Model):
_name = "zhy.sale.line"
_description = u"销售订单"
name = fields.Char(string=u'产品名称')
order_id = fields.Many2one('zhy.sale', string=u'销售订单', require=True, ondelete='cascade', index=True, copy=False)
Python2.7中, string中文前要加u
<odoo>
<menuitem id="menu_2" name="销售" sequence="12" />
<menuitem id="menu_2_0" name="CRM" sequence="1" parent="menu_2" />
<menuitem id="menu_2_1" name="销售" sequence="2" parent="menu_2" />
<menuitem id="menu_2_99" name="常用报表" sequence="99" parent="menu_2" />
<menuitem id="menu_2_100" name="设置" sequence="100" parent="menu_2" />
odoo>
<odoo>
<record id="odoo_form_zhy_sale_views" model="ir.ui.view">
<field name="name">zhy.sale.formfield>
<field name="model">zhy.salefield>
<field name="arch" type="xml">
<form string="表单">
<sheet>
<div class="oe_button_box" name="button_box">
div>
<group>
<group>
<field name="name"/>
group>
<group>
group>
group>
sheet>
form>
field>
record>
<record id="odoo_tree_zhy_sale_views" model="ir.ui.view" >
<field name="name">zhy.sale.treefield>
<field name="model">zhy.salefield>
<field name="priority">1field>
<field name="arch" type="xml">
<tree string="列表">
<field name="name"/>
tree>
field>
record>
<record id="odoo_action_zhy_sale_views" model="ir.actions.act_window">
<field name="name">销售模块field>
<field name="type">ir.actions.act_windowfield>
<field name="res_model">zhy.salefield>
<field name="view_type">formfield>
<field name="view_mode">tree,formfield>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Create the first course
<p>p>
p>
field>
record>
<menuitem action="odoo_action_zhy_sale_views" name="zhy_销售" id="menu_zhy_sale_views" sequence="0" />
odoo>
<odoo>
<record id="odoo_form_zhy_sale_views" model="ir.ui.view">
<field name="name">zhy.sale.formfield>
<field name="model">zhy.salefield>
<field name="arch" type="xml">
<form string="表单">
<sheet>
<div class="oe_button_box" name="button_box">
div>
<group>
<group>
<field name="name"/>
<field name="price_unit" string="金额" attrs='{"invisible": [("active", "=", True)]}'/>
<field name="users_ids" widget="many2many_tags"/>
group>
<group>
<field name="date_order"/>
<field name="delivary_date"/>
<field name="priority"/>
<field name="user_id"/>
<field name="id_object"/>
<field name="active"/>
<field name="sequence" attrs='{"invisible": [("active", "=", True)]}'/>
group>
<notebook colspan="4">
<page string="明细" autofocus="autofocus">
<field name="order_line"/>
<field name="note"/>
page>
<page string="正文">
<field name="content"/>
page>
notebook>
group>
sheet>
form>
field>
record>
<record id="odoo_tree_zhy_sale_views" model="ir.ui.view" >
<field name="name">zhy.sale.treefield>
<field name="model">zhy.salefield>
<field name="priority">1field>
<field name="arch" type="xml">
<tree string="列表">
<field name="name"/>
tree>
field>
record>
<record id="odoo_action_zhy_sale_views" model="ir.actions.act_window">
<field name="name">销售模块field>
<field name="type">ir.actions.act_windowfield>
<field name="res_model">zhy.salefield>
<field name="view_type">formfield>
<field name="view_mode">tree,formfield>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Create the first course
<p>p>
p>
field>
record>
<menuitem action="odoo_action_zhy_sale_views" name="zhy_销售" id="menu_zhy_sale_views" sequence="0" />
odoo>
<odoo>
<data>
<record model="ir.ui.view" id="course_form_view">
<field name="name">course.formfield>
<field name="model">openacademy.coursefield>
<field name="arch" type="xml">
<form string="Course Form">
<sheet>
<group>
<field name="name"/>
<field name="responsible_id"/>
group>
<notebook>
<page string="描述">
<field name="description"/>
page>
<page string="授课">
<field name="session_ids">
<tree string="授课注册">
<field name="name"/>
<field name="instructor_id"/>
tree>
field>
page>
<page string="关于">
这是一个关于notebook的案例
page>
notebook>
sheet>
form>
field>
record>
<record model="ir.ui.view" id="course_search_view">
<field name="name">course.searchfield>
<field name="model">openacademy.coursefield>
<field name="arch" type="xml">
<search>
<field name="name"/>
<field name="description"/>
search>
field>
record>
<record model="ir.ui.view" id="course_tree_view">
<field name="name">course.treefield>
<field name="model">openacademy.coursefield>
<field name="arch" type="xml">
<tree string="课程详情">
<field name="name"/>
<field name="responsible_id"/>
tree>
field>
record>
<record model="ir.actions.act_window" id="course_list_action">
<field name="name">Coursesfield>
<field name="res_model">openacademy.coursefield>
<field name="view_type">formfield>
<field name="view_mode">tree,formfield>
<field name="context" eval="{'search_default_my_courses': 1}"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">Create the first course
p>
field>
record>
<menuitem id="main_openacademy_menu" name="公开教程"/>
<menuitem id="openacademy_menu" name="公开教程"
parent="main_openacademy_menu"/>
<menuitem id="courses_menu" name="课程" parent="openacademy_menu"
action="course_list_action"/>
<record model="ir.ui.view" id="session_form_view">
<field name="name">session.formfield>
<field name="model">openacademy.sessionfield>
<field name="arch" type="xml">
<form string="Session Form">
<sheet>
<group>
<group string="综合的">
<field name="course_id"/>
<field name="name"/>
<field name="instructor_id"/>
<field name="active"/>
group>
<group string="时间表">
<field name="start_date"/>
<field name="duration"/>
<field name="seats"/>
<field name="taken_seats" widget="progressbar"/>
group>
group>
<label for="attendee_ids"/>
<field name="attendee_ids"/>
sheet>
form>
field>
record>
<record model="ir.ui.view" id="session_tree_view">
<field name="name">session.treefield>
<field name="model">openacademy.sessionfield>
<field name="arch" type="xml">
<tree string="Session Tree" >
<field name="name"/>
<field name="course_id"/>
<field name="taken_seats" widget="progressbar"/>
tree>
field>
record>
<record model="ir.actions.act_window" id="session_list_action">
<field name="name">Sessionsfield>
<field name="res_model">openacademy.sessionfield>
<field name="view_type">formfield>
<field name="view_mode">tree,formfield>
record>
<menuitem id="session_menu" name="授课"
parent="openacademy_menu"
action="session_list_action"/>
data>
odoo>
<odoo>
<record id="seq_zhy_sale_sequence" model="ir.sequence">
<field name="name">zhy.salefield>
<field name="code">zhy.salefield>
<field name="prefix">A%(year)s%(month)s%(day)sfield>
<field name="padding">5field>
<field name="company_id" eval="False" />
record>
odoo>
# 从 ir.squence中取出self._name字段,然后给他生成一个编号
name = fields.Char(string=u'单据编号', default=lambda self: self.env['ir.sequence'].next_by_code(self._name) or 'New')
from datetime import datetime, timedelta
from odoo.tools import float_is_zero, float_compare, DEFAULT_SERVER_DATETIME_FORMAT
# 获取当前日期
default=fields.Datetime.now
date_order = fields.Datetime(string=u'单据日期', readonly=True, index=True, copy=False, default=fields.Datetime.now)
# 在当前日期上加上多少天(一般是单据日期和发货日期)
# days中的值可以是正值(向前加多少天),也可以是负值(向后减多少天)
default=lambda self: datetime.strptime(fields.Datetime.now(), DEFAULT_SERVER_DATETIME_FORMAT) + timedelta(days=1)
widget="float_time"表示的是可以输入一个时间
hours = fields.Float(string=u’单价’, default=0.0, digits=(10, 2), readonly=False)
# 过滤字段, 可以让用户只能选择当前的用户
<field name="user_id" domain="[('id', '=', 1)]"/>
domain="[('id', '=', 1)]"
<header>
<button name="button_loading_draft" states="处理中" string="重置草稿" type="object" class="highlight" />
<button name="button_done_draft" states="已审核" string="重置草稿" type="object" class="highlight" />
<button name="button_loading" states="草稿" string="提交草稿" type="object" class="highlight" />
<button name="button_done" states="处理中" string="审核" type="object" class="highlight" />
<field name='state' widget='statusbar' statusbar_visible='草稿,处理中,已审核' />
header>
state = fields.Selection([
(u'草稿', u'草稿'),
(u'处理中', u'处理中'),
(u'已审核', u'已审核'),
], string='单据状态', readonly=True, copy=False, default=u'草稿', track_visibility='onchange')
@api.multi
def button_loading_draft(self):
return self.write({'state': u'草稿'})
@api.multi
def button_done_draft(self):
return self.write({'state': u'草稿'})
@api.multi
def button_loading(self):
return self.write({'state': u'处理中'})
@api.multi
def button_done(self):
return self.write({'state': u'已审核'})
@api.multi
def action_done(self):
return self.write({'state': u'取消'})
注意: xml文件中button的name值要和.py文件中函数的名称相对应;
几种状态的对应,可以在视图是观察字段所对应的后端值来定
<record id="odoo_form_zhy_sale_views" model="ir.ui.view">
<field name="name">zhy.sale.formfield>
<field name="model">zhy.salefield>
<field name="arch" type="xml">
<form string="表单">
<header>
<button name="button_loading_draft" states="处理中" string="重置草稿" type="object" class="highlight" />
<button name="button_done_draft" states="已审核" string="重置草稿" type="object" class="highlight" />
<button name="button_loading" states="草稿" string="提交草稿" type="object" class="highlight" />
<button name="button_done" states="处理中" string="审核" type="object" class="highlight" />
<field name='state' widget='statusbar' statusbar_visible='草稿,处理中,已审核' />
header>
<sheet>
<div class="oe_button_box" name="button_box">
div>
<group>
<group>
<field name="name"/>
<field name="price_unit" string="金额" attrs="{'readonly': [('state', 'in', (u'处理中', u'已审核'))]}" />
<field name="users_ids" widget="many2many_tags" />
group>
<group>
<field name="date_order"/>
<field name="delivary_date"/>
<field name="priority"/>
<field name="hours" widget="float_time"/>
<field name="user_id" />
<field name="id_object" />
<field name="active"/>
<field name="sequence" attrs='{"invisible": [("active", "=", True)]}'/>
group>
<notebook colspan="4">
<page string="明细" autofocus="autofocus">
<field name="order_line"/>
<field name="note" widget="html"/>
page>
<page string="正文">
<field name="content"/>
page>
notebook>
group>
sheet>
form>
field>
record>
# 后端中添加只读状态
# 要结合后端中的state这个字段来进行设置的
price_unit = fields.Float(string=u'单价', default=0.0, digits=(10, 2),
readonly=True, states={u'草稿': [('readonly', False)], u'处理中': [('readonly', False)]})
state = fields.Selection([
(u'草稿', u'草稿'),
(u'处理中', u'处理中'),
(u'已审核', u'已审核'),
], string='单据状态', readonly=True, copy=False, default=u'草稿', track_visibility='onchange')
一般的情况下, xml的优先级都要高于.py文件中的优先级
<odoo>
<data>
<record id="sale_groups" model="ir.module.category">
<field name="name">销售zfield>
record>
<record id="sale_users" model="res.groups">
<field name="name">销售z-用户field>
<field name="category_id" ref="sale_groups" />
<field name="users" eval="[(4, ref('base.user_root'))]" />
record>
<record id="sale_manager" model="res.groups">
<field name="name">销售z-经理field>
<field name="category_id" ref="sale_groups" />
<field name="implied_ids" eval="[(4, ref('sale_users'))]" />
<field name="users" eval="[(4, ref('base.user_root'))]" />
record>
data>
odoo>
<header>
<button name="button_loading_draft" states="处理中" string="重置草稿" type="object" class="highlight" groups="aa_zhy.sale_users" />
<button name="button_done_draft" states="已审核" string="重置草稿" type="object" class="highlight" groups="aa_zhy.sale_manager" />
<button name="button_loading" states="草稿" string="提交草稿" type="object" class="highlight" groups="aa_zhy.sale_users" />
<button name="button_done" states="处理中" string="审核" type="object" class="highlight" groups="aa_zhy.sale_manager"/>
<field name='state' widget='statusbar' statusbar_visible='草稿,处理中,已审核' />
header>
在实际的项目中, 我们给用户设置了提交审核的权限之后,我们可以用另外的一个用户登录
去查看我们创建的模块,新创建的用户中,我们是没有办法看到我们创建的模块的,这个时候我们需要在管理员账户的设置群组中,找到我们谁知的权限管理模块, 然后进去,给我们的用户设置模块的访问权限即可.
<!--设置权限组, aa_zhy表示的是文件夹的名称, sale_manager表示的是security.xml文件中设置的权限-->
<!--groups='aa_zhy.sale_manager'-->
price_unit = fields.Float(string=u'单价', default=0.0, digits=(10, 2), readonly=True, groups='aa_zhy.sale_manager')
同样,也可以把
groups='aa_zhy.sale_manager'
放到xml中也是可以的.
设置完成之后, 就可以用另外的一个账户登录,这个时候,就会发现, 不是管理员用户,就不能查看金额字段了。
_inherit = ['mail.thread']
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers" />
<field name="message_ids" widget="mail_thread" />
div>
track_visibility='onchange'
这个是结合message使用的, 是把更改的一些信息显示到下面的message中.track_visibility='always'
用户不更改信息的是时候,message也会记录下这些信息.<!--批量关注的两种方法-->
<!--users_ids是后端定义的多对多的关联字段; 8表示的是当前的这个用户的id-->
self.message_subscribe_user(users_ids=(self.user_id.id))
self.message_subscribe(partner_ids=[8])
<!--批量取消的两种方法-->
self.message_unsubscribe_user(users_ids=(self.user_id.id))
self.message_unsubscribe(partner_ids=[8])
<!--主要是一个many2one字段-->
class res_city1(models.Model):
_name = "res.city1"
_description = u"省"
name = fields.Char(string=u'省')
class res_city2(models.Model):
_name = "res.city2"
_description = u"市"
name = fields.Char(string=u'市')
city1_id = fields.Many2one('res.city1', string=u'明细', )
class res_city3(models.Model):
_name = "res.city3"
_description = u"区"
name = fields.Char(string=u'区')
city2_id = fields.Many2one('res.city2', string=u'明细', )
class zhy_sale_line(models.Model):
_name = "zhy.sale.line"
_description = u"销售订单"
name = fields.Char(string=u'产品名称')
order_id = fields.Many2one('zhy.sale', string=u'销售订单', require=True, ondelete='cascade', index=True, copy=False)
# 这个地方是定义三个多对一的id字段, 关联对应的表单,提取内容
city1_id = fields.Many2one('res.city1', string=u'省')
city2_id = fields.Many2one('res.city2', string=u'市')
city3_id = fields.Many2one('res.city3', string=u'区')
# onchang时间, 通过第三级(或则是最下级)一级一级向上查询
@api.onchange('city3_id')
def onchange_city3_id(self):
values = {}
if self.city3_id:
# city2_id(市)表示的是通过三级的id,找到二级的id.(反向查找)
values['city2_id'] = self.city3_id.city2_id.id
# city1_id(省)表示的是通过三级区的id,找到二级市的id,再找到一级省的id.(反向查找)
values['city1_id'] = self.city3_id.city2_id.city1_id.id
self.update(values)
class res_city1(models.Model):
_name = "res.city1"
_description = u"省"
name = fields.Char(string=u'省')
class res_city2(models.Model):
_name = "res.city2"
_description = u"市"
name = fields.Char(string=u'市')
city1_id = fields.Many2one('res.city1', string=u'明细', )
class res_city3(models.Model):
_name = "res.city3"
_description = u"区"
name = fields.Char(string=u'区')
city2_id = fields.Many2one('res.city2', string=u'明细', )
<notebook colspan="4">
<page string="明细" autofocus="autofocus">
<field name="order_line">
<tree string="列表" editable="bottom">
<field name="city1_id" />
<field name="city2_id" domain="[('city1_id', '=', city1_id)]" />
<field name="city3_id" domain="[('city2_id', '=', city2_id)]" />
tree>
field>
<field name="note" widget="html"/>
page>
<page string="正文">
<field name="content"/>
page>
notebook>
# 新增数量,单价,和小计等字段.这些字段都是要float类型
# depends中依赖的是自己心定义的两个字段,如果这两个字段发生变化,则执行这个函数
@api.depends('product_uom_qty', 'price_unit')
def _compute_amout(self):
for order in self:
order.price_subtotal = order.product_uom_qty * order.price_unit
product_uom_qty = fields.Float(string=u'数量', required=True, default=1.0)
price_unit = fields.Float(string=u'单价', required=True, default=0.0, digits=(10, 2))
# compute是关联一个函数.我们在这个函数中可以写计算逻辑
price_subtotal = fields.Float(compute='_compute_amout', string=u'小计')
# 在其他的表中做关联和金额合计的时候
# 这个表中依赖的是外键表中的一个字段;通过外键表找到这个字段,然后对这个字段进行操作
@api.depends('order_line.price_subtotal')
def _compute_amount(self):
for order in self:
total = sum(line.price_subtotal for line in order.order_line)
order.amount = total
amount = fields.Float(compute='_compute_amount', string=u'小计')
order_line = fields.One2many('zhy.sale.line', 'order_id', string=u'订单明细行', copy=True, auto_join=True)
# @api.multi表示的是可以选择多个 重写unlink()方法
# 当界面点击删除事件的时候会触发
@api.multi
def unlink(self):
for order in self:
# 判断当前的用户和表单的创建用户是否一致, 如果不一致不允许删除.
if order.user_id:
# user_id(字段名称)
if order.user_id.id != self._uid:
raise UserError(u'只能删除自己的单据')
if order.state != u"草稿":
raise UserError(u'只能删除草稿单据')
# self.env['amos.workflow'].sudo.seach([('res_model', '=', self._name), ('res_id', '=', order.id)]).unlink()
# self.env['if.message'].sudo.seach([('res_model', '=', self._name), ('res_id', '=', order.id)]).unlink()
# 关联的是哪张表
return super(zhy_sale, self).unlink
# 项目中是实际会用到的
@api.multi
def unlink(self):
for order in self:
if order.user_id:
if order.user_id.id != self._uid:
raise UserError(u'只能删除自己的单据aaaa')
# 这个地方有问题, 当不能删除的时候, 注意下判断条件(可以使用debug),打印出判断条件对比下就可以了.
if order.state.encode('utf-8') != "草稿":
print(order.state, type(order.state))
raise UserError(u'只能删除草稿单据bbbb')
return super(zhy_sale, self).unlink()
# 其他的写法
# @api.multi
# def unlink(self):
# if any(order.state in (u'处理中', u'已审核') for order in self):
# raise exceptions.UserError(u'只能删除草稿单据啊啊啊啊啊啊.')
# super(zhy_sale, self).unlink()
# vals表示的是界面传入进来的所有的值
# self._context表示的传入进来的上下文的值
# 当创建的时候会触发
@api.model
def create(self, vals):
# print(self._context, u'这是上下文')
# print(vals, u'这是界面传入进来的值')
if vals.get('name', 'New') == 'New':
# 这个地方表示是判断传入进来的值中有没有company_id字段, 如果有的话, 设置一个单据编号
if 'company_id' in vals:
# with_context传上下文的 next_by_code下一个字段
vals['name'] = self.env['ir.sequence'].with_context(force_company=vals['company_id']).next_by_code(self._name) or 'New'
else:
vals['name'] = self.env['ir.sequence'].next_by_code(self._name) or 'New'
# 可以指定修改某个值
vals['hours'] = 100.00
line = super(zhy_sale, self).create(vals)
return line
# odoo中常用的widget
widget="statusbar" 头部状态条标签
widget="email" 电子邮件地址标签
widget="selection" 下拉选择标签
widget="mail_followers" 关注者标签
widget="mail_thread" 消息标签
widget="progressbar" 进度条,按百分比标签
widget="one2many_list" 一对多列表标签
widget="many2many_tags" 多对多显示标签
widget="url" 网站链接标签
widget='image' 图片标签
widget="many2many_kanban" 看版标签
widget="handler" 触发标签
widget="radio" 单选标签
widget="char_domain" 字符域标签
widget="monetary" 价格(和精度位数相关)标签
widget="float_time" 单精度时间标签
widget="html" html相关标签
widget="pad" pad显示相关标签
widget="date" 日期标签
widget="monetary" 金额标签
widget='text' 文本标签
widget="sparkline_bar" 燃尽标签
widget="checkbox" 复选框标签
widget="reference" 关联标签
<field name="partner_type" nolabel="1" widget="selection" string="" \
attrs="{'required': [('payment_type', 'in', ('inbound', 'outbound'))], \
'invisible': [('payment_type', 'not in', ('inbound', 'outbound'))], \
'readonly': [('state', '!=', 'draft')]}"/>
# 当修改表单中数据 的时候会被触发
@api.multi
def write(self, vals):
print(vals, u'我是修改之后的值')
if vals.has_key('price_unit'):
print(vals.has_key('price_unit'), 1111111)
if vals['price_unit'] > 100000:
print(isinstance(vals['price_unit'], str))
print(vals['price_unit'], type(vals['price_unit']))
raise UserError(u'警告: 你没有权限修改')
return super(zhy_sale, self).write(vals)
<div class="oe_button_box" name="button_box">
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive">
<field name="active" widget="boolean_button" options='{"terminology": "archive"}' />
button>
div>
@api.multi
def toggle_active(self):
for recode in self:
print(recode, "我来了")
recode.active = not recode.active
隐藏新建,隐藏修改,隐藏删除
create=“false”
edit=“false”
delete=“false”
<form string="表单" create="false" edit="false" delete="false">
form>
或者
<form string="表单" create="0" edit="0" delete="0">
form>
# 两张变中的字段也是可以关联的
# 表zhy.sale中的字段
delivery_date = fields.Date(string=u'发货日期',track_visibility='onchange',)
# 表zhy.sale.line中的字段
# order_id是关联的其他表
order_id = fields.Many2one('zhy.sale', string=u'销售订单', require=True, ondelete='cascade', index=True, copy=False)
# related="表中外键表的字段" 一定要注意字段的类型Date一定要和关联的其他表的字段类型一致
delivery_date = fields.Date(related='order_id.delivery_date', string=u'发货日期', store=True)