完全不一样的。
self.env.ref()参数是xml id,用来获取xml id对应的记录
self.env['model的_name'],用来获取model的引用
iooop
-
self.env['res.parter']和self.env.ref('res.parter')区别? -
view中使用context.get()了解到view中可以使用context.get来做一些动态的处理,比如根据context里面的某个元素的值,来处理是否隐藏某个字段。
搜了一下源代码,这样的应用还是很多的,比如:odoo\addons\base\res\res_bank_view.xml,<record id="view_partner_bank_search" model="ir.ui.view"> <field name="name">res.partner.bank.search</field> <field name="model">res.partner.bank</field> <field name="arch" type="xml"> <search string="Bank Accounts"> <field name="bank_name" filter_domain="['|', ('bank_name','ilike',self), ('acc_number','ilike',self)]" string="Bank Name"/> <field name="company_id" invisible="context.get('company_hide', True)"/> <field name="partner_id"/> </search> </field> </record>
对于上面的代码,在视图中获取key为company_hide的context值,从而决定是否隐藏字段company_id。
我尝试搜索源代码,看是在哪里设置company_hide的,但是没有找到任何处理的地方。我的问题是,这里的company_hide是在哪里产生和设置的?如果没有任何地方设置company_hide,那上面的代码设置那段invisible的处理又有什么意义? -
odoo时间的处理?关于odoo处理时间的机制,对以下现象感到困惑:
测试一:
如果在odoo的python代码中,以下代码
datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
会产生utc时间(不带时区的),结果跟datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')是完全一样的!测试二:
如果在同一台机器的python终端上运行datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),却会产生一个带时区的本地时间(结果比上面的增加8小时)
同样的python内置的datetime,为什么产生不一样的结果?odoo中间做了什么处理了吗?另外,上面是的测试时在linux(debian)下。如果在windows中,现象跟上述不一样。
测试一和测试二产生的时间是一致的,结果都是带时区的时间。
========================EDIT=======================
受到以下文章的启发:
http://radzhang.iteye.com/blog/2328612
原来,在odoo/__init__.py
初始化时做了个“时区hack”,将系统环境的时区设置成了'UTC',经这一处理后,上述测试的现象和结果就能解释通了。并且经过这么处理后,在odoo代码中使用datetime.datetime.now()和datetime.datetime.utcnow()是完全一样的效果,不用纠结用哪一个。需要注意odoo/__init__.py
中的“时区hack”仅对linux环境起作用。至于在windows中的现象,其实在最新的odoo版本中,通过命令行启动的odoo实例也能实现上述的“时区hack”,但是在
Windows的IDE
(比如eclipse)中,odoo官方好像还没有解决的方法来实现这种“时区hack”。具体说法可以参考github中odoo/__init__.py
的comments(https://github.com/odoo/odoo/commit/07bf7bf4f3af49f18a06000ef50ef90d8ad90224 ) -
record rules问题-没写权限也可以修改记录@Joshua ,谢谢,基本上明白了。简单归纳如下,不知道还有没有理解错误或偏差。
- perm_write = False时不表示该条record rule的用户组没有write权限(我想这也是界面上Record Rule记录对应的字段label叫做“Apply for Write ”而不是直接叫“Write”的原因)
- 要控制用户组对某些记录无法Write,则需要定义用户组对哪些条件(condition1)的记录可以Write,除去condition1之外的所有记录就不能Write了。
- 如果用户A属于不同的组,并且这些组中有多条record rule都对同一个model定义了能Write的条件(比如rule1可以Write的条件为condition1的记录,比如rule2可以Write的条件为condition2的记录),则用户A可以Write (condition1 OR condition2)的记录,不能write除 (condition1 OR condition2)之外的----也就是[not (condition1 OR condition2)]----记录。
不过。。。如果odoo直接设计成 perm_write = False的记录就无法Write,是不是更好理解一些??
-
record rules问题-没写权限也可以修改记录@Joshua 在 record rules问题-没写权限也可以修改记录 中说:
多基础数据模型是没有记录规则的
谢谢@Joshua !
如果odoo设计就是如此的话,这样的设计完全不符合正常逻辑。其实访问规则ACL已经对用户组“授权”。这样的设计会对权限控制带来一些不必要的麻烦,比如我上面加了两条记录规则后,虽然两条规则的perm_unlink都是False,我还是可以成功删除记录。我必须要告诉系统,用户组能删除哪些条件的记录后,系统才知道除此条件之外的记录不能删除,如果我不想让这个组的用户删除任何记录呢?我还需要定义一条perm_unlink为True,并且domain条件为[(1, '!=', 1)]的记录规则。。。 -
record rules问题-没写权限也可以修改记录在odoo10里我有一个model,该model有且仅有一条record rule,该record rule设置没有写权限,具体是这样定义的:
<record id="todo_task_user_rule" model="ir.rule"> <field name="name">rule1</field> <field name="model_id" ref="model_todo_task"/> <field name="domain_force">[('create_uid','!=',user.id)]</field> <field name="groups" eval="[(4,ref('base.group_user'))]"/> <field eval="0" name="perm_unlink"/> <field eval="0" name="perm_write"/> <field eval="1" name="perm_read"/> <field eval="1" name="perm_create"/> </record>
该条record rule生效后,测试发现用户还可以修改满足('create_uid','!=',user.id)条件的记录。经过反复测试和对比已有的模块,发现需要给同组用户添加一个perm_write=True(当然,domain为不一样)的record rule才能实现该组的用户无法修改记录,我添加的record rule如下:
<record id="todo_task_user_rule" model="ir.rule"> <field name="name">rule2</field> <field name="model_id" ref="model_todo_task"/> <field name="domain_force">[('create_uid','=',user.id)]</field> <field name="groups" eval="[(4,ref('base.group_user'))]"/> <field eval="0" name="perm_unlink"/> <field eval="1" name="perm_write"/> <field eval="1" name="perm_read"/> <field eval="1" name="perm_create"/> </record>
之后查看源代码,发现odoo/odoo/addons/base/ir/ir_rule.py的_compute_domain()处理逻辑,当找不到ir.rule记录时,则检查权限当通过处理,而其SQL语句是这样的:
query = """ SELECT r.id FROM ir_rule r JOIN ir_model m ON (r.model_id=m.id) WHERE m.model=%s AND r.active AND r.perm_{mode} AND (r.id IN (SELECT rule_group_id FROM rule_group_rel rg JOIN res_groups_users_rel gu ON (rg.group_id=gu.gid) WHERE gu.uid=%s) OR r.global) """.format(mode=mode)
问题在于where条件r.perm_{mode}(我的例子,这里就是r.perm_write),当数据库中没有perm_write=True的记录的记录时,这里的不可能查到任何ir.rule记录。这样就会导致我例子中出现的问题。
是不是哪里有问题?odoo这样的设计真是非常的奇怪。。
-
控制window action的访问权限?谢谢jeffery回复。可能odoo本身就是这么设计的,个人觉得这种权限的策略设计太过宽松了。普通用户在地址栏敲个window action的id就可以看到管理员的配置页面及配置的内容,实在是很难让我接受。
-
控制window action的访问权限?请问如何控制window action的安全性?
现在只要用户在地址栏输入action记录的id值,就可以看到对应的视图了。
虽然用户可能没有权限创建或修改记录,但是看到某些窗口信息总归不好。
比如Sales/Setting的window action记录的id为283.普通用户在地址栏修改action参数的值为283就能看到所有的设置的值。官方可以指定window action的组,但是仅仅用来控制是否在界面上显示。 -
一个one2many字段的创建问题[quote author=iooop link=topic=17606.msg32244#msg32244 date=1463042576]
有一个model(以下称为model_a),model_a中有一个one2many字段(以下称为field_1,对应MA的外键字段称为ma_id--是个many2one字段)。
修改model_a的记录时,可以在form中添加field_1的记录,可以选择ma_id字段的值为正在修改的model_a对应的记录。这是没有问题的
新建model_a记录时,添加field_1的记录的时候,由于这时该新建的model_a记录还没有保存到数据库,ma_id字段的下拉列表里是没有该条model_a记录的。这就导致了无法在创建父记录的时候,同时创建one2many记录,有什么办法解决吗?
[/quote]
感谢@上海-开阖-Jeff的解答,已经找到解决方法。
原来在field_1对应的form定义中不能包括外键ma_id的定义,去掉就好了,系统会自己处理并且保存ma_id的值。
另外如果field_1对应的form定义在别的地方也会调用(这样就不能删除外键ma_id的定义)。可以在<tree>...</tree>后加入一个不包含ma_id的<form/>定义。 -
一个one2many字段的创建问题有一个model(以下称为model_a),model_a中有一个one2many字段(以下称为field_1,对应MA的外键字段称为ma_id--是个many2one字段)。
修改model_a的记录时,可以在form中添加field_1的记录,可以选择ma_id字段的值为正在修改的model_a对应的记录。这是没有问题的
新建model_a记录时,添加field_1的记录的时候,由于这时该新建的model_a记录还没有保存到数据库,ma_id字段的下拉列表里是没有该条model_a记录的。这就导致了无法在创建父记录的时候,同时创建one2many记录,有什么办法解决吗? -
Ir.actions.act_window的view_type字段的作用?[quote author=Jeff link=topic=17529.msg31982#msg31982 date=1457440375]
view type现在只支持 tree 和 form两个值
tree是一个对象的多条记录按parent_id组织成一个树,可切换的只有树形和form两个view mode
当view type为from时,view mode有7个可选值。你可以在任务的菜单里看到六种,第七种在工作流菜单里有
[/quote]
Hi @Jeff,谢谢指点。
我后来翻看了系统中的window action,view_type属性为tree的很少,只有10个左右,正如你说的设成'tree'的作用是用[b]树形[/b]视图来展示有层级关系的列表,比如部门的层级结构,多公司中的母公司/子公司的层级结构等等。
我也找到了官方对这个属性的解释:View type: Tree type to use for the tree view, set to 'tree' for a [b]hierarchical [/b]tree view, or 'form' for a regular list view
如果这个属性叫做tree_type,值为'tree'或'list'就好理解了。 -
Ir.actions.act_window的view_type字段的作用?[quote author=卓忆 link=topic=17529.msg31972#msg31972 date=1457396877]
[quote author=iooop link=topic=17529.msg31960#msg31960 date=1457003830]
经常看到数据文件里定义window action的时候设置view_type,不知道其含义。查阅了官方文档和论坛,没有找到答案。
OpenERP 6文档中的说明是这样的:
[quote]view_type is set to form when the action must open a new form view, and is set to tree when the action must open a new tree view.
(来自:https://doc.odoo.com/6.0/developer/2_7_menu_action/7_2_actions/)[/quote]
看完还是不知道是什么意思。谁能解释一下?
谢谢!
[/quote]
试着回答下,抛砖引玉:
Odoo中有好几种视图类型,
[attachimg=1]
点击可切换
大致 视图有以下几个类型:
tree(列表视图) 有点像excel, 联系人的默认视图就是 列表视图,
form表单视图, 点击具体联系人 ,进入表单视图,
kanban 看板视图,(商机的默认视图)
甘特视图,
图表视图,各种透视图
日历视图,
[/quote]
HI 卓忆.你这里列举的应该是view_mode属性的值。 -
Ir.actions.act_window的view_type字段的作用?经常看到数据文件里定义window action的时候设置view_type,不知道其含义。查阅了官方文档和论坛,没有找到答案。
OpenERP 6文档中的说明是这样的:
[quote]view_type is set to form when the action must open a new form view, and is set to tree when the action must open a new tree view.
(来自:https://doc.odoo.com/6.0/developer/2_7_menu_action/7_2_actions/)[/quote]
看完还是不知道是什么意思。谁能解释一下?
谢谢! -
Tree 中的button的context的问题我发现tree中的button无法正常的设置context,比如我定义了以下的tree view,其中有一个button,button中根据某个字段的值(这里是partner_id)...
<field name="arch" type="xml">
<tree>
<field name="name" />
<field name="user_id" invisible="1"/>
<field name="partner_id" invisible="1"/>
<button name="do_apply_rfd" string="apply" type="object" [b]context="{'ctx_partner_id': partner_id}"[/b]/>
</tree>
</field>
button点击后,在方法do_apply_rfd中我能通过context获取到ctx_partner_id的值,但是,每次点击button的ctx_partner_id值竟然是一样的,值永远是我第一次点击按钮时那个按钮对应的partner_id!
究竟是哪里的问题?如果这是正常情况,那么button的context设置有什么意义?在这个例子中,我怎样才能将partner_id传给do_apply_rfd方法?
=========== EDIT(2016-3-3) ===========
看到有人回复,我也更新一下这个问题。
上述问题,可能是个bug(odoo8),button通过context属性传递的东西有上述描述的问题:第一次点击一条记录对应的botton时值是对的,之后点击别的记录的button,值还是第一次点的那个。
上述的例子里传的值是字段(partner_id)的值,我后来直接在方法里通过self.partner_id来获取。 -
如何使model在某些状态下不能编辑?[quote author=Joshua link=topic=17491.msg31796#msg31796 date=1453428560]
通过Record Rule 来定义 读/写规则
[/quote]
是的,这是其中一种解决方法:能根据条件控制用户不能修改数据,但是界面效果并不好。
用户还是可以点击“编辑”,只是在保存的时候提示没有权限。 -
如何使model在某些状态下不能编辑?[quote author=digitalsatori link=topic=17491.msg31789#msg31789 date=1453381272]
字段定义上的states参数就是派这个用处的。比如说下面这段代码:
[font=Verdana][/font]<br /><br /> 'name': fields.char('Order Reference', required=True, copy=False,<br /> readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, select=True),<br />
[font=Verdana][size=78%]
表示订单的编码(Order reference)除了在‘draft'和’sent‘状态下是可编辑的,在其他状态下都是不可编辑的(read only)[/size][/font]
[/quote]
感谢回复。
不过个人觉得这种方式对我说的情况并不适合,原因有二:
1. 由于需求是整条记录(form)都不能编辑,所以如果根据字段去设置的话,model的每个字段都要设置成readonly,然后设置states属性。即使真的这么全设置了,出来的效果是用户可以点击“编辑”,然后出来一个没有一个字段可以编辑的表单,真的很奇怪。
2. 这种方法只能根据state字段来判断字段是否可编辑,不能根据别的字段的值去做判断。
如果没有简单的办法将"编辑"按钮隐藏或disable掉,能不能在点击“编辑”按钮之后做判断,如果不符合条件不让其进入编辑状态呢? -
如何使model在某些状态下不能编辑?现实情况中,经常会遇到在某些情况下业务数据不能编辑的情况,比如订单提交后就不能编辑。
我当前能想到的解决方法是,覆盖model的wirte方法,在保存的时候做逻辑判断处理,不符合的raise Error。
虽然能达到目的,这种方法的效果并不理想,理想的效果应该是对那些不符合条件的model记录直接不显示edit按钮,用户不能进入编辑状态。
想到过在fields_view_get里做处理,根据model的字段值座逻辑判断,然后修改返回的xml,将form的edit属性改为false。
实践之后发现由于浏览器会先请求fields_view_get,之后才获取model数据,所以fields_view_get里根本无法得到model的记录id。所以这个方法行不通。
请问解决这类问题,常用的做法是怎么样的? -
Odoo的字段校验问题[quote author=kingxj link=topic=17465.msg31713#msg31713 date=1452567694]
楼主,不知你解决这个问题没有,指教一下。。谢谢
[/quote]
在odoo官方论坛上搜索了一番,没有找到好的解决方案。也没有找现成的addon
期待国内大神解答。 -
请问怎么在field里面进行判断[quote author=mrshelly link=topic=17462.msg31685#msg31685 date=1452072605]
<button icon="V.gif" attrs="{'invisible': [('xxxxx', '!=', 2)]}"/>
<button icon="X.gif" attrs="{'invisible': [('xxxxx', '!=', 0)]}"/>
[/quote]
这种方法会将“√”和“×”分别显示在两列吧? 效果应该是像下面这样的
city_name city_code ....
--------------------------------------
√ name1 code1
√ name2 code2
× name3 code3
√ name4 code4
× name5 code5
...............
有办法将√和×显示在同一列吗?