【问题标题】:Odoo: _get_state() takes at least 4 arguments (4 given) in xml viewOdoo:_get_state() 在 xml 视图中至少需要 4 个参数(4 个给定)
【发布时间】:2016-08-27 19:48:31
【问题描述】:

这是我的代码。我想在定义其模型类之前获取当前记录的 id_employee:

def _get_state(self, cr, uid, context=None):
    idemployee = ""
    for adv in self.browse(cr, uid, ids, context):
        id_employee = adv.id_employee
        if id_employee is None:
            idemployee = _default_employee(self, cr, uid, context=None)
        else:
            idemployee = id_employee

    sql = " SELECT C.id AS id, C.sequence, C.name \
                   FROM wf_group_member A \
           LEFT JOIN wf_group B ON B.id = A.group_id \
           LEFT JOIN wf_process BB ON BB.id = B.process_id \
           LEFT JOIN wf_state C ON C.group_id = B.id \
           LEFT JOIN hr_employee D ON D.id = A.member_id \
           WHERE LOWER(code) = 'ca' AND member_id = %s ORDER BY sequence "
    res = []
    cr.execute(sql, [(idemployee)])
    ardata = cr.fetchall()
    for data in ardata:
        res.append((data[1], data[2]))
    return res

这是我的模型类,我把它放在 _get_state 函数之后

class cashadvance(osv.osv):
    _name = 'ga.cashadvance'
    _columns = {
        'id_user'                   : fields.many2one('res.users', string='User', required=True, readonly=True),
        'state'                     : fields.selection(_get_state, 'Status', readonly=True),
        'id_employee'               : fields.many2one('hr.employee', string='Employee', required=True, readonly=True),
    }

当我调用 _get_state 函数时,它引发了错误:

Error details:
global name 'ids' is not defined
None" while parsing /opt/custom-addons/comben/views/cashadvance_view.xml:4, near
<record id="cashadvance_list" model="ir.ui.view">
            <field name="name">cashadvance_list</field>
            <field name="model">ga.cashadvance</field>
            <field name="arch" type="xml">
                <tree string="Cashadvance List">
                    <field name="id_employee"/>
                    <field name="category_id"/>
                    <field name="est_date_from" string="Est Date From"/>
                    <field name="est_date_to" string="Est Date To"/>
                    <field name="description"/>
                    <field name="state"/>
                </tree>
            </field>
        </record>

谁能帮帮我,谢谢

【问题讨论】:

  • idemployee = _default_employee(self, cr, uid, context=None) 应该做什么,具体来说_default_employee 是什么?
  • _default_employee是通过uid调用hr_employee中的employee_id的函数,它会返回employee_id,没问题

标签: python openerp


【解决方案1】:

_get_state 必须是类的一部分才能在类之外使用它,你传入的 self 不被视为 python self 即当前实例,它被视为正常函数的参数。

Python 不会为您传递 self,让我稍微偏离一下并重现您遇到的错误。看看这段代码

def func(self,cr, uid, ids, context=None):
    pass

class func_test:
    def __init__(self):
        func(1, 1, 1, context=1)

a = func_test()

这是引发的错误(确保使用 python2 运行)

Traceback (most recent call last):
  File "script.py", line 8, in <module>
    a = func_test()
  File "script.py", line 6, in __init__
    func(1, 1, 1, context=1)
TypeError: func() takes at least 4 arguments (4 given)

python实际上是正确的,尽管它具有误导性,该函数至少需要四个参数,因为上下文是关键字参数,并且在函数定义时已经填充,但它仍然缺少一个参数,因为函数在外面一个类,因此通常称为self 的第一个参数被视为普通参数(因为它是一个函数)而不是方法(类中的函数)。所以从左到右开始selfcruid将被填写为111离开ids,此时python会呼救,因为没有找到值对于那个参数,如果我们将该函数移到类中并使用self.func 调用它,则当前实例会自动为我们传递。

class func_test:
    def func(self,cr, uid, ids, context=None):
        pass

    def __init__(self):
        self.func(1, 1, 1, context=1)

a = func_test()

当然你仍然可以拥有func(self, 1, 1, 1, context=1),但这会违背方法的目的

但请注意,python3 比 python2 更聪明,并且处理这种场景更好,这是 python3 的回溯

Traceback (most recent call last):
  File "script.py", line 8, in <module>
    a = func_test()
  File "script.py", line 6, in __init__
    func(1, 1, 1, context=1)
TypeError: func() missing 1 required positional argument: 'ids'

它清楚地告诉我们在函数调用中没有为ids 提供任何值

所以回到 Odoo 你的代码应该是这样的

from openerp.osv import osv, fields

class cashadvance(osv.osv):
    _name='comben.cashadvance'

    def _get_state(self, cr, uid, context=None):
        idemployee = ""

        ids = self.search(cr, uid, [], context=context) # you probably want to search for all the records
        for adv in self.browse(cr, uid, ids, context=context):
            id_employee = adv.id_employee
            if id_employee is None:
                idemployee = self._default_employee(cr, uid, ids, context=None) # might raise singleton error if more than one record is returned
            else:
                idemployee = id_employee.id

        sql = " SELECT C.id AS id, C.sequence, C.name \
                   FROM wf_group_member A \
           LEFT JOIN wf_group B ON B.id = A.group_id \
           LEFT JOIN wf_process BB ON BB.id = B.process_id \
           LEFT JOIN wf_state C ON C.group_id = B.id \
           LEFT JOIN hr_employee D ON D.id = A.member_id \
           WHERE LOWER(code) = 'ca' AND member_id = %s ORDER BY sequence "
        res = []
        cr.execute(sql, [(idemployee)])
        ardata = cr.fetchall()
        for data in ardata:
            res.append((data[1], data[2]))

       return res 

    _columns = {
        'id_user': fields.many2one('res.users', string='User', required=True, readonly=True),
        'state': fields.selection(_get_state, string='Status', readonly=True),
        'id_employee': fields.many2one('hr.employee', string='Employee', required=True, readonly=True),
    }

并将_default_employee 移动到类主体中,这样你就可以这样称呼它

self._default_employee(cr, uid, context=None) # python implicitly passes self for you

xml 视图

<record id="cashadvance_list" model="ir.ui.view">
  <field name="name">cashadvance list</field>
  <field name="model">comben.cashadvance</field>
  <field name="arch" type="xml">
    <tree string="Cashadvance List">
      <field name="id_employee"/>
      <field name="id_user"/>
      <field name="state"/>
    </tree>
  </field>
</record>

【讨论】:

  • 我遵循了您的代码,并引发了错误:“未定义全局名称 'ids'”。从以下部分看来:for adv in self.browse(cr, uid, ids, context): need more help please
  • 哎呀抱歉,我在 _get_state 参数中添加了 id,但随后引发错误:ParseError:“无效的视图定义错误详细信息:get_state() 在解析时至少需要 4 个参数(4 个给定)无” /opt/custom-addons/comben/views/cashadvance_view.xml:4,差不多,还是一样的错误,我真的很困惑
  • 您是否遵循我的最新代码....并且请粘贴此引发错误的 xml
  • 是的,我做到了,这是 xml:ParseError:Invalid view definition 错误详细信息:get_state() 在解析 /opt/custom-addons/comben/ 时需要至少 4 个参数(给定 4 个)None" views/cashadvance_view.xml:4,靠近 cashadvance_listcomben.cashadvance
  • 我在下面的评论中描述了这一切
【解决方案2】:

在这种情况下,你想要这个:

def _get_state(self, cr, uid, ids, context=None):
        current_record=self.browse(cr, uid, ids)
        idemployee = current_record[0].id_employee

    sql = " SELECT C.id AS id, C.sequence, C.name \
                   FROM wf_group_member A \
           LEFT JOIN wf_group B ON B.id = A.group_id \
           LEFT JOIN wf_process BB ON BB.id = B.process_id \
           LEFT JOIN wf_state C ON C.group_id = B.id \
           LEFT JOIN hr_employee D ON D.id = A.member_id \
           WHERE LOWER(code) = 'ca' AND member_id = %s ORDER BY sequence "
    res = []
    cr.execute(sql, [(idemployee)])
    ardata = cr.fetchall()
    for data in ardata:
        res.append((data[1], data[2]))
    return res

【讨论】:

  • 感谢您的回答,但是我需要在列之前获取字段值,因为我想将该字段值用作get_state函数中的参数cr.execure进行状态字段选择
  • 我遵循了您的代码,并在 xml 中引发错误:ParseError: "Invalid view definition Error details: global name 'ids' is not defined
  • 当我将 ids 放入 get_state 时,def get_state(self, cr, uid, context=None): 它引发错误:get_state() 在 xml 视图中至少需要 4 个参数(4 个给定)
猜你喜欢
  • 1970-01-01
  • 2017-10-15
  • 2014-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-12
相关资源
最近更新 更多