[FIX] base: avoid KeyError in res_partner._display_address
In some case, users use custom `address_format` with keys that do not
exists. This lead to errors in odoo and upgrade process. Avoid
`KeyError` by using defaultdict with `str` value.
upg-361146
upg-361241
```
Traceback (most recent call last):
File "/home/odoo/src/odoo/14.0/odoo/service/server.py", line 1201, in preload_registries
registry = Registry.new(dbname, update_module=update_module)
File "/home/odoo/src/odoo/14.0/odoo/modules/registry.py", line 89, in new
odoo.modules.load_modules(registry._db, force_demo, status, update_module)
File "/home/odoo/src/odoo/14.0/odoo/modules/loading.py", line 457, in load_modules
force, status, report, loaded_modules, update_module, models_to_check)
File "/home/odoo/src/odoo/14.0/odoo/modules/loading.py", line 349, in load_marked_modules
perform_checks=perform_checks, models_to_check=models_to_check
File "/home/odoo/src/odoo/14.0/odoo/modules/loading.py", line 227, in load_module_graph
migrations.migrate_module(package, 'post')
File "/home/odoo/src/odoo/14.0/odoo/modules/migration.py", line 180, in migrate_module
migrate(self.cr, installed_version)
File "/tmp/tmp1bew9m7l/migrations/website/14.0.1.0/post-adapt-footer-data.py", line 69, in migrate
address = html_escape(partner._display_address(without_company=True))
File "/home/odoo/src/odoo/14.0/odoo/addons/base/models/res_partner.py", line 950, in _display_address
return address_format % args
KeyError: 'town_name'
```
closes odoo/odoo#96703
X-original-commit: 81bf1d2101202a4a6cb832004500129905c2d3be
Signed-off-by: Christophe Simonis <chs@odoo.com>
This commit is contained in:
committed by
Christophe Simonis
parent
170aa05182
commit
ef5a9612f7
@@ -10,6 +10,7 @@ import threading
|
||||
import re
|
||||
|
||||
import requests
|
||||
from collections import defaultdict
|
||||
from lxml import etree
|
||||
from random import randint
|
||||
from werkzeug import urls
|
||||
@@ -967,13 +968,13 @@ class Partner(models.Model):
|
||||
# get the information that will be injected into the display format
|
||||
# get the address format
|
||||
address_format = self._get_address_format()
|
||||
args = {
|
||||
args = defaultdict(str, {
|
||||
'state_code': self.state_id.code or '',
|
||||
'state_name': self.state_id.name or '',
|
||||
'country_code': self.country_id.code or '',
|
||||
'country_name': self._get_country_name(),
|
||||
'company_name': self.commercial_company_name or '',
|
||||
}
|
||||
})
|
||||
for field in self._formatting_address_fields():
|
||||
args[field] = getattr(self, field) or ''
|
||||
if without_company:
|
||||
|
||||
@@ -182,3 +182,22 @@ class TestPartner(TransactionCase):
|
||||
partner_form.company_type = 'person'
|
||||
partner_form.name = 'Philip'
|
||||
self.assertEqual(partner_form.user_id, test_parent_partner.user_id)
|
||||
|
||||
def test_display_address_missing_key(self):
|
||||
""" Check _display_address when some keys are missing. As a defaultdict is used, missing keys should be
|
||||
filled with empty strings. """
|
||||
country = self.env["res.country"].create({"name": "TestCountry", "address_format": "%(city)s %(zip)s"})
|
||||
partner = self.env["res.partner"].create({
|
||||
"name": "TestPartner",
|
||||
"country_id": country.id,
|
||||
"city": "TestCity",
|
||||
"zip": "12345",
|
||||
})
|
||||
before = partner._display_address()
|
||||
# Manually update the country address_format because placeholders are checked by create
|
||||
self.env.cr.execute(
|
||||
"UPDATE res_country SET address_format ='%%(city)s %%(zip)s %%(nothing)s' WHERE id=%s",
|
||||
[country.id]
|
||||
)
|
||||
self.env["res.country"].invalidate_model()
|
||||
self.assertEqual(before, partner._display_address().strip())
|
||||
|
||||
Reference in New Issue
Block a user