Skip to content

Handling an empty / None option in selects. #64

@TrilceAC

Description

@TrilceAC

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.

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions