ValueError: Expected singleton: res.partner(1, 12, 29, 30, 36) - res.partner - Odoo v10 community

ValueError: Expected singleton: res.partner(1, 12, 29, 30, 36) - res.partner - Odoo v10 community

我正在继承 res.partner 模型,这是从 v8 到 v10 社区的迁移。

违规方法如下所示:

@api.depends('company_id')
def _get_country_code(self):
    """
    Return the country code of the user company. If not exists, return XX.
    """
    #context = dict(self._context or {})
    for partner in self:
        user_company = self.env['res.company'].browse(self.company_id)
        #NOTE: replace code name with your real field name where you want to see value 
        partner.code = user_company.partner_id and user_company.partner_id.country_id \
            and user_company.partner_id.country_id.code or 'XX'

@api.multi
def _get_uid_country(self): 
    """ Return a dictionary of key ids as invoices, and value the country code
    of the user company.
    """
    res = {}.fromkeys(self._get_country_code()) 
    return res

现在每次我点击一个客户或供应商 (res.partner),它会抛出这个:

Traceback (most recent call last):
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/http.py", line 638, in _handle_exception
return super(JsonRequest, self)._handle_exception(exception)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/http.py", line 675, in dispatch
result = self._call_function(**self.params)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/http.py", line 331, in _call_function
return checked_call(self.db, *args, **kwargs)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/service/model.py", line 119, in wrapper
return f(dbname, *args, **kwargs)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/http.py", line 324, in checked_call
result = self.endpoint(*a, **kw)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/http.py", line 933, in __call__
return self.method(*args, **kw)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/http.py", line 504, in response_wrap
response = f(*args, **kw)
File "/home/kristian/odoov10/odoo-10.0rc1c-20161005/odoo/addons/web/controllers/main.py", line 862, in call_kw
return self._call_kw(model, method, args, kwargs)
File "/home/kristian/odoov10/odoo-10.0rc1c-20161005/odoo/addons/web/controllers/main.py", line 854, in _call_kw
return call_kw(request.env[model], method, args, kwargs)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/api.py", line 681, in call_kw
return call_kw_multi(method, model, args, kwargs)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/api.py", line 672, in call_kw_multi
result = method(recs, *args, **kwargs)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/models.py", line 2995, in read
values[name] = field.convert_to_read(record[name], record, use_name_get)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/models.py", line 5171, in __getitem__
return self._fields[key].__get__(self, type(self))
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/fields.py", line 860, in __get__
self.determine_value(record)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/fields.py", line 969, in determine_value
self.compute_value(recs)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/fields.py", line 924, in compute_value
self._compute_value(records)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/fields.py", line 916, in _compute_value
getattr(records, self.compute)()
File "/home/kristian/odoov10/gilda/l10n_ve_fiscal_requirements/model/partner.py", line 90, in _get_uid_country
res = {}.fromkeys(self._get_country_code()) #ids, cr, uid, context=context)
File "/home/kristian/odoov10/gilda/l10n_ve_fiscal_requirements/model/partner.py", line 68, in _get_country_code
user_company = self.env['res.company'].browse(self.company_id)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/fields.py", line 854, in __get__
record.ensure_one()
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/models.py", line 4783, in ensure_one
raise ValueError("Expected singleton: %s" % self)
ValueError: Expected singleton: res.partner(1, 33, 8, 18, 22, 23)

我认为这与这条线有关 user_company = self.env['res.company'].browse(self.company_id) 但我不是 100% 确定。

有什么想法吗?

编辑

旧API原始方法:

def _get_country_code(self, cr, uid, context=None):
    """
    Return the country code of the user company. If not exists, return XX.
    """
    context = context or {}
    user_company = self.pool.get('res.users').browse(
        cr, uid, uid, context=context).company_id
    return user_company.partner_id and user_company.partner_id.country_id \
        and user_company.partner_id.country_id.code or 'XX'

def _get_uid_country(self, cr, uid, ids, field_name, args, context=None):
    """ Return a dictionary of key ids as invoices, and value the country code
    of the user company.
    """
    context = context or {}
    res = {}.fromkeys(ids, self._get_country_code(cr, uid,
                                                  context=context))
    return res

您应该尝试使用 _get_uid_country 函数:

for record in self.browse(): result = {}.fromkeys(record._get_country_code(), False)

您可以尝试替换此行:

user_company = self.env['res.company'].browse(self.company_id)

有了这个

user_company = self.env['res.company'].browse(partner.company_id)

然后让我们知道

当你使用 @api.multi self 是一个 RecordSet 时:

RecordSet can have 0 or 1 or more records when you use self.getSomeThing this works if the RecordSet have one record, but if it have more than one an exception is raised because it will not know witch record you want to ask. so if you use @api.multi try to always to loop the recordSet. @api.depends is also like @api.multi the self is a RecordSet.

for rec in self :
     rec.getSomeThing

or use @api.one here the self is always one Record but is not recommanded because it call the getSomeThing according to the number of records in your view, so for form view it's not a problem because it has only one but for tree view you can imagine.

我试着缩短了一点:

uid_country = fields.Char(
    string="Country Code of Current User",
    compute="_get_uid_country")

@api.multi
@api.depends('company_id')  # there should be a better trigger field
def _get_uid_country(self):
    """ Compute country code by current users company """
    country_code = self.env.user.company_id.partner_id.country_id.code or 'XX'
    for partner in self:
        partner.update({'uid_country': country_code})

这应该足够了。在我看来,没有真正的触发字段,每次调用合作伙伴时都会计算计算字段。但它应该有效。