fix: prefer attr over key lookup when getting model values

applies to both forms and grids.

the base model class can still handle `obj[key]` but now it is limited
to the column fields only, no association proxies.

so, better to just try `getattr(obj, key)` first and only fall back to
the other if it fails.

unless the obj is clearly a dict in which case try `obj[key]` only
This commit is contained in:
Lance Edgar 2024-08-19 11:09:49 -05:00
parent 1d56a4c0d0
commit 0eeeb4bd35
2 changed files with 14 additions and 9 deletions

View file

@ -1359,12 +1359,15 @@ class Form(object):
def obtain_value(self, record, field_name): def obtain_value(self, record, field_name):
if record: if record:
try:
if isinstance(record, dict):
return record[field_name] return record[field_name]
except KeyError:
return None try:
except TypeError: return getattr(record, field_name)
return getattr(record, field_name, None) except AttributeError:
pass
return record[field_name]
# TODO: is this always safe to do? # TODO: is this always safe to do?
elif self.defaults and field_name in self.defaults: elif self.defaults and field_name in self.defaults:

View file

@ -586,12 +586,14 @@ class Grid(WuttaGrid):
if isinstance(obj, sa.engine.Row): if isinstance(obj, sa.engine.Row):
return obj._mapping[column_name] return obj._mapping[column_name]
try: if isinstance(obj, dict):
return obj[column_name] return obj[column_name]
except KeyError:
try:
return getattr(obj, column_name)
except AttributeError:
pass pass
except TypeError: return obj[column_name]
return getattr(obj, column_name, None)
def render_currency(self, obj, column_name): def render_currency(self, obj, column_name):
value = self.obtain_value(obj, column_name) value = self.obtain_value(obj, column_name)