Get None from a Fields data in instead of an empty string
Question:
I have this field in the WTForms
form
name = StringField('Name', validators = [Optional(), Length(max = 100)])
When the field is submitted empty then form.name.data
will, as expected, contain an empty string.
Is there some way to make it return None
in instead of an empty string? It is just because it is very convenient to deal with null
in the database like in this update
:
update t
set
name = coalesce(%(name)s, name),
other = coalesce(%(other)s, other)
With the above code I don’t need to check if the field is empty or not and take actions accordingly be it in the Python code on in the SQL code. The null
with the coalesce
solves that easily.
Answers:
There is the filters
parameter to the Field
constructor
name = StringField(
'Name',
validators = [Optional(), Length(max = 100)],
filters = [lambda x: x or None]
)
http://wtforms.readthedocs.org/en/latest/fields.html#the-field-base-class
In my case I added a base class for my forms (all forms are inherited from this class):
class BaseFrom(FlaskForm):
@property
def fields(self) -> dict:
"""Returns a dict of fields with values, a value='' substitutes with None"""
def process_item(item):
if isinstance(item, dict):
return process_dict(item)
elif isinstance(item, list):
return process_list(item)
elif item == '':
return None
return item
def process_dict(d: dict) -> dict:
return {k: process_item(v) for k, v in d.items()}
def process_list(l_: list) -> list:
return [process_item(v) for v in l_]
return process_dict({f: value.data for f, value in self._fields.items()})
So, when an object is being mapped from form input to dataclass, the mapper uses fields
property to retrieve data from the form
@dataclass
class BaseModel:
@classmethod
def from_form(cls, obj: dict):
self = object.__new__(cls)
for f in dataclasses.fields(cls):
setattr(self, f.name, obj.get(f.name))
return self
d = BaseModel.from_form(form_instance.fields)
where form_instance
is an instance of a class inherited from ‘BaseForm’
I have nested forms, so this method will convert all empty inputs to None recursively
I have this field in the WTForms
form
name = StringField('Name', validators = [Optional(), Length(max = 100)])
When the field is submitted empty then form.name.data
will, as expected, contain an empty string.
Is there some way to make it return None
in instead of an empty string? It is just because it is very convenient to deal with null
in the database like in this update
:
update t
set
name = coalesce(%(name)s, name),
other = coalesce(%(other)s, other)
With the above code I don’t need to check if the field is empty or not and take actions accordingly be it in the Python code on in the SQL code. The null
with the coalesce
solves that easily.
There is the filters
parameter to the Field
constructor
name = StringField(
'Name',
validators = [Optional(), Length(max = 100)],
filters = [lambda x: x or None]
)
http://wtforms.readthedocs.org/en/latest/fields.html#the-field-base-class
In my case I added a base class for my forms (all forms are inherited from this class):
class BaseFrom(FlaskForm):
@property
def fields(self) -> dict:
"""Returns a dict of fields with values, a value='' substitutes with None"""
def process_item(item):
if isinstance(item, dict):
return process_dict(item)
elif isinstance(item, list):
return process_list(item)
elif item == '':
return None
return item
def process_dict(d: dict) -> dict:
return {k: process_item(v) for k, v in d.items()}
def process_list(l_: list) -> list:
return [process_item(v) for v in l_]
return process_dict({f: value.data for f, value in self._fields.items()})
So, when an object is being mapped from form input to dataclass, the mapper uses fields
property to retrieve data from the form
@dataclass
class BaseModel:
@classmethod
def from_form(cls, obj: dict):
self = object.__new__(cls)
for f in dataclasses.fields(cls):
setattr(self, f.name, obj.get(f.name))
return self
d = BaseModel.from_form(form_instance.fields)
where form_instance
is an instance of a class inherited from ‘BaseForm’
I have nested forms, so this method will convert all empty inputs to None recursively