OpenERP 7:客户端域过滤器中的关系字段

Pri*_*ckZ 1 python xml openerp

这里显示我的错误

2013-04-23 05:36:03,877 17001 ERROR demo openerp.sql_db: bad query: SELECT "res_company".id FROM "res_company" WHERE "res_company".id = 'deduction_id.bpl_company_id.id' ORDER BY "res_company"."name"  
Traceback (most recent call last):
  File "/home/bellvantage/Documents/openerp-7.0/openerp-7/openerp/sql_db.py", line 226, in execute
    res = self._obj.execute(query, params)
DataError: invalid input syntax for integer: "deduction_id.bpl_company_id.id"
LINE 1: ...y".id FROM "res_company" WHERE "res_company".id = 'deduction...
                                                             ^

2013-04-23 05:36:03,878 17001 ERROR demo openerp.osv.osv: Uncaught exception
Traceback (most recent call last):
Run Code Online (Sandbox Code Playgroud)

这里显示我试图添加域过滤器的代码

class estate_bank_deductions(osv.osv):
    _name = 'bpl.estate.bank.deductions'
    _description = 'Estate Bank Deductions'
    _columns = {
                'deduction_id':fields.many2one('bpl.deduction.estate.data', 'Bank Deductions', ondelete='cascade'),
                'name': fields.many2one('bpl.deduction.registration', 'Deduction', domain="[('type','=','bank'),('bpl_company_id.id','=','deduction_id.bpl_company_id.id')]"),
                'bank_id': fields.many2one('bpl.bank.registration', 'Bank Name'),
                'branch_id': fields.many2one('bpl.branch.registration', 'Branch'),
        }
Run Code Online (Sandbox Code Playgroud)

这是我父母一类房地产银行扣除类的一部分

_name = 'bpl.deduction.estate.data'
_description = 'BPL Deduction Estate Data'
_columns = {
            'bpl_company_id':fields.many2one('res.company', 'Company', help='Company'),
Run Code Online (Sandbox Code Playgroud)

请帮我理清一下.我的域名过滤机制中是否有任何遗漏或者这种方式不正确.


亲爱的,

还有一件事需要澄清,现在需要将我的领域定义为fields.function

但问题是在添加域过滤器之后还将其他不相关的记录加载到我的下拉列表中(在我添加了widget ="selection"属性之后).然后如何限制它们.我已经发布了这个问题

希望你能就此提出建议......再次感谢你

odo*_*ony 8

它无论如何都无济于事.模型字段仅支持两种域过滤器:

  • 服务器端(列表)域,指定为元组列表:只能是静态的,one2many并且many2many主要用于和字段.当读取字段的值列表时,这些过滤器将应用于服务器端,并且永远不会在客户端使用.域只能包含每个域元素右侧的常量.有效的服务器端域的示例是:

    # filter deductions based on an imaginary "confirmed" boolean field
    deduction_ids = fields.one2many('bpl.estate.bank.deductions', 'bank_id',
                                    string="Confirmed Deductions",
                                    domain=[('confirmed', '=', True)])
    
    Run Code Online (Sandbox Code Playgroud)
  • 客户端(字符串)域,指定为服务器端域的字符串表示形式:可以是静态的或动态的,并且主要用于many2one字段,并且从不在服务器端进行评估.它们只是在使用该字段的任何视图中复制,并在客户端进行解释,以过滤该字段的可用选项列表.通过引用视图中包含的任何其他字段的名称,可以使每个域元素的右侧动态化,并在评估域时将其替换为字段值.将以与write()保存更改时传递的格式相同的格式返回字段值.有效客户端域的示例是:

    # only allow choosing a branch that belongs to the right bank registration
    # (here `branch_id` refers to the current value of the `branch_id` field
    # in the form view
    'branch_id': fields.many2one('bpl.branch.registration', 'Branch',
                                 domain="[('branch_id','=',branch_id)]")
    
    Run Code Online (Sandbox Code Playgroud)

    更新:注意,您不能widget="selection"与客户端域结合使用,因为此选项会将您的many2one字段转换为虚假,fields.selection其选项在服务器端进行静态评估.在这种情况下,您的客户端域将被忽略,可用值列表将永远不会更改.现在,如果您只是想避免用户创建新值,您可以限制访问权限以防止这种情况,如果您想避免显示查看/编辑目标对象的图标,您可以添加options='{"no_open": True}'到表单视图中的字段.

问题

在您的情况下,您似乎希望使用客户端域根据deduction_id字段的当前值进行过滤.但是您的域表达式('bpl_company_id.id','=','deduction_id.bpl_company_id.id')不正确:

  • 左侧必须引用字段或字段路径,并且.id后缀在此处无用,bpl_company_id足以在该many2one字段上进行过滤.
  • 右侧可以是动态的也可以是静态的,具体取决于您是将其设为常量还是变量.如果您引用该值,'deduction_id.bpl_company_id.id'那么您将m2oID(或m2o删除.id后缀的名称)与文字字符串值进行比较"deduction_id.bpl_company_id.id",当然不是您想要的.
    如果您按照user2310008的建议删除引号,您将确实使其成为动态,但该值的值deduction_id将是所选"扣除"的ID!您不能browse_record像服务器端那样将它视为(类似ActiveRecord的对象),因此当您执行此操作时,"deduction_id.bpl_company_id.id"您将收到错误,因为整数没有bpl_company_id属性.

实现这种过滤的常用方法是on_changededuction_id字段上添加一个方法,并使用它name通过方法可以返回的domain键动态地更改列的域onchange.像这样的东西:

    <!-- in the XML view -->
    <field name="deduction_id" on_change="onchange_deduction_id(deduction_id)"/>
    <field name="name"/>
Run Code Online (Sandbox Code Playgroud)
    # in the python model
    def onchange_deduction_id(self, cr, uid, ids, deduction_id, context=None):
        if deduction_id:
            deduction = self.pool['bpl.deduction.estate.data'].browse(cr, uid,
                                                                      deduction_id,
                                                                      context)
            return {'domain': {'name': [('bpl_company_id', '=',
                                         deduction.bpl_company_id.id)]}
        return {} # or perhaps a default domain?
Run Code Online (Sandbox Code Playgroud)