Когда, почему и как избежать KeyError в Odoo Development

Я заметил, что некоторые пользовательские модули, которые я разрабатываю, могут быть установлены в базах данных с записями, в то время как другие выдают сообщение KeyError, если база данных не пуста (нет записей). Обычно ошибки появляются, когда модуль содержит вычисляемые поля. Итак, кто-нибудь знает, почему это происходит? и как должен выглядеть мой код, чтобы избежать подобных ошибок? пример вычисляемого поля, которое выдает эти ошибки, выглядит следующим образом:

from odoo import models, fields, api
from num2words import num2words

Class InheritingAccountMove(models.Model):
   _inherit = 'account.move'

total_amount_text = fields.Char(string='Total', compute='_compute_total_amount_text', store=True)

    @api.depends('amount_total')
    def _compute_total_amount_text(self):
        lang_code = self.env.context.get('lang') or self.env.user.lang
        language = self.env['res.lang'].search([('iso_code', '=', lang_code)])
        separator = language.read()[0]['decimal_point']
        for record in self:
            decimal_separator = separator
            user_language = lang_code[:2]
            amount = record.amount_total
            amount_list = str(amount).split(decimal_separator)
            amount_first_part = num2words(int(amount_list[0]), lang=user_language).title() + ' '
            amount_second_part = amount_list[1]
            if len(amount_second_part) == 0:
                amount_text = amount_first_part + '00/100'
            elif len(amount_second_part) < 2:
                amount_text = amount_first_part + amount_second_part + '0/100'
            else:
                amount_text = amount_first_part + amount_second_part[:2] + '/100'

            record.total_amount_text = amount_text

person Simon Capriles    schedule 23.02.2020    source источник


Ответы (2)


ОБНОВЛЕНО
Причина, по которой ваш код имеет проблему в этой ситуации, заключается в том, что, когда в таблице нет записей (во время установки), ваш цикл не запускается, что не приводит к присвоению значения вычисляемого поля, поэтому добавьте первую строку кода в функцию
self.total_amount_text = False
Это необходимо для присвоения значения вычисляемому полю в функции вычисления из Odoo 13 и, возможно, 12
----- -------------------------------------------------- ---------
Другими причинами могут быть:
Эта ошибка возникает, когда кто-то пытается получить доступ к ключу из словаря, который не существует,

language.read()[0]['decimal_point']

словарь может не иметь 'decimal_point' во время установки модуля, который, возможно, возвратил эту ошибку, распространенный способ справиться с этим - проверить, существует ли ключ перед доступом к нему. например,

if 'decimal_point' in language.read()[0].keys() также, словарь также может быть пустым, в этом случае language.read()[0] выдаст ошибку

person Muhammad Yusuf    schedule 23.02.2020
comment
Я изменил код, добавив это условие, но все равно получаю сообщение об ошибке ... - person Simon Capriles; 26.02.2020
comment
@SimonCapriles, можно ли показать журнал ошибок и обновленный код? - person Muhammad Yusuf; 26.02.2020
comment
Хорошо, нет необходимости в коде и журнале, добавьте self.total_amount_text = False в первой строке после функции, и я обновил ответ - person Muhammad Yusuf; 27.02.2020

Я изменил свой код, сделав его специально для испанского, и ошибка больше не появляется. Я ценю ответ Мухаммеда, возможно, он прав, но в любом случае вот модифицированный код:

@api.depends('invoice_line_ids')
    def _compute_total_amount_text(self):
        for record in self:
            amount = record.amount_total
            amount_list = str(amount).split('.')
            amount_first_part = num2words(int(amount_list[0]), lang='es').title() + ' '
            amount_second_part = amount_list[1]
            if len(amount_second_part) == 0:
                amount_text = amount_first_part + '00/100'
            elif len(amount_second_part) < 2:
                amount_text = amount_first_part + amount_second_part + '0/100'
            else:
                amount_text = amount_first_part + amount_second_part[:2] + '/100'
            record.total_amount_text = amount_text
person Simon Capriles    schedule 27.02.2020