关于domain,如何跨类比较?
-
@BraidTim
以下方式也行:
<field name="B2" domain="[('B1', 'operator', parent.A1)]"/>搜索域中的每个元组需要有3个元素,格式为:('field_name','operator',value),其中:
(1) field_name必须是对象模型的字段的有效名称,可使用点符号进行many2one关系,例如“partner_id.country”是有效值。
(2) 运算符必须是一个带有有效比较运算符的字符串:=,!=,>,> =,<,<=,like,ilike,in,not in,child_of
(3) 值必须是与field_name的值进行比较的有效值,具体取决于其类型 -
@Felix_Cheng
field name="B2" domain="[('B1', 'operator', parent.A1)]"
似乎在many2one里面使用domain,字段名字直接就是A里面的名字
我这儿是odoo10,field name="B2" domain="[('A1', 'operator', value)]"这样写就能运行,但是类似上面那样写
field name="B2" domain="[('B1', '=', 1)]"
直接就显示
ValueError: Invalid field u'B1' in leaf "<osv.ExtendedLeaf: (u'B1', u'=', 1) on meeu_v1_warehouse_product_manage (ctx: )>"
顺便问问value是不需要引号的吗? -
@BraidTim 更正一下上贴,搞反了,不好意思:<field name="B2" domain="[('A1', 'operator', B1)]"/>, value是number类型直接写值不加引号,布尔型False或True,String类型加上引号。具体看数据类型,的确是不太容易的。
如:
domain="[('state','=','done')]"
domain="[('user_id','=',uid)]"
domain="[('user_id','=',False)]"
domain="[('reconcile_id','=', False), ('credit', '>',0),('amount_to_pay','>',0)] "
代码生成如下:
class Test_b(models.Model):
_name='test.b'
_b1=fields.Integer(string='B1')
_b2=fields.Many2one('test.a', string='B2')class Test_a(models.Model):]
_name='test.a'
_a1=fields.Integer(string='A1')XML
<record id='test_b_form' model='ir.ui.view'>
xxxxxx....
yyyyyy...
<form ....>
<field name="b1" />
<field name="b2" domain="[('a1', '<', b1)]"
</form>
其中a1为父表(Many2one)字段,b1为本表字段。在父表筛选记录,该记录的a1字段值比b1的value小
openerp7.0 在domain写'>'是允许的,但是高版本要写转义'<' -
@felix_cheng
谢谢,换过来就对了。本类里面的字段也不用引号是吧?之前我可能加了引号,系统当字符串处理所以还是不行。
也就是说字段和数字,bool都不用加引号,字符串需要加引号这样?
对比的时候数据类型会自动转换么?比如如果我想比较date这种,看起来是字符串但是有大小之分的。还是要专门写函数什么的? -
@braidtim
关于date可以写成
<field name="domain">[('from_date', '<', '2017-08-01')]
是没有问题的,domain将转换成SQL的Where, 换句话说上面的domain在底层数据库翻译为
SELECT * FROM table_xxx WHERE from_date < '2017-08-01', (这个可以通过的)也可以从另外角度来看:如,
<field name="domain">[('from_date', '<', 'First date to school')],
SQL为:
SELECT * FROM table_xxx WHERE from_date < 'First date to school', 这明显类型不兼容结论:domain比较类型兼不兼容, 想想看SQL通不通过就可以验证。
--(3) 值必须是与field_name的值进行比较的有效值,具体取决于其类型(这个是我在上面贴里提到的)至于其他数字类型的如Integer,Float,Boolean应该可以在一定程度上互相比较,有兴趣的话你可以自己
试试。 -
@felix_cheng
先多谢细心指导
我在另一个帖子也看到您关于domain的解答,那个帖子问的是直接写在many2one定义里面的domain。我想请问问domain直接在定义字段的时候写和在view中写有什么有略,两种分别有什么适用场景? -
@braidtim
很好的问题 。
在服务器端python里定义《B object A字段》 的domain,她定义于数据库水平层级(最底层)。换句话说,python端的domain有效于所有使用《B object A字段》的view。而在view中定义的domain,只对该view有效。
如果你不需要数据库端给该字段预过滤,就可以考虑直接写在view中(这个是我个人看法)有点像required定义于python端和view端的意思, 在python端是表示not null于DB级别,即使代码层create,write也不许该字段为False。而在view端required只是要求在界面该字段中必须填入些内容,对于数据库的约束没有一点影响。