-
Notifications
You must be signed in to change notification settings - Fork 28
Description
Last week I reported an issue into wtforms-alchemy regarding its inability to render a CountryField with an empty option for those cases when the user does not want to select one and None should be stored. But it seems to me that the place to report it might be this project because it seems that the real issue is how wtforms-components should render a None option for selects.
On the issue already mentinoed I tried to add an empty option as you see in the example that I provided. On the following different case, with different data type, the issue is just the same:
class Person(Model):
id = Column(Integer, primary_key=True, index=True)
uid = Column(Integer, unique=True, nullable=True, index=True)
guid = Column(
Integer,
nullable=True,
index=True,
info={
'label': 'UNIX GID',
'description': 'Id del grupo de UNIX al que pertenece el usuario.',
'choices': [
(None, ''),
(500, '500: IT'),
(502, '502: Management'),
]
}
)
Note that I'm using sqlalchemy-utils and this model is translated to a form, being guid a select with three options. At the time of rendering the form, this fails because wtforms-components tries to coerce None into int, which causes an exception on line 270.
wtforms-components/wtforms_components/widgets.py
Lines 262 to 270 in 523caeb
| try: | |
| coerce_func, data = mixed | |
| except TypeError: | |
| selected = mixed | |
| else: | |
| if isinstance(data, list) or isinstance(data, tuple): | |
| selected = coerce_func(value) in data | |
| else: | |
| selected = coerce_func(value) == data |
wtforms_components/widgets.py", line 270, in render_option
selected = coerce_func(value) == data
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
Trying options based on strings raises a different exception on the same line because it doesn't know how to covnert the option into a int. Supose that che choice is ('', '') or ('None', ''), in any of both cases the problem is that it is unable to convert the option into an int:
/wtforms_components/widgets.py", line 270, in render_option
selected = coerce_func(value) == data
ValueError: invalid literal for int() with base 10: ''
Would it be a reasonable solution to test whether the given value is None, and if so, do not perform the data coercion? I'm happy to help if this approach seems reasonable.