Reputation: 639
I'm having trouble with what I thought would be a very simple task in WTForms: checking to see if a field has had any data entered in it. It seems that the data method returns different results depending on the type of field, so I can't use it generically to test this.
I'm using this in a Flask app. In my forms declaration, I have:
title = StringField('Title')
signed = RadioField('Signed?', choices = [('Y','yes'),('N','no')])
Then, in my views.py, after an "if form.is_submitted()":
print('Title raw_data is %r' % form.title.raw_data)
print('Title data is %r' % form.title.data)
if form.title.raw_data:
print ("Title raw data is True")
if form.title.data:
print ("Title data is True")
print('Signed raw_data is %r' % form.signed.raw_data)
print('Signed data is %r' % form.signed.data)
if form.signed.raw_data:
print ("Signed raw data is True")
if form.signed.data:
print ("Signed data is True")
When I run this and fill out neither field in the form, I get:
Title raw_data is ['']
Title data is ''
Title raw data is True
Signed raw_data is []
Signed data is 'None'
Signed data is True
That is, form.title.data returns the empty string, so I can use this for a test; form.signed.data returns the string 'None', rather than None, so it fails the "if form.signed.data" test. Thus I have to use form.signed.raw_data, which returns an empty list, which is False. But I can't use raw_data in all instances, because form.title.raw_data doesn't return an empty list, it returns a list consisting of the empty string, which is not True
Is there a way I can test if any kind of field is filled out, or do I have to switch between data and raw_data depending on the kind of field? This is counterintuitive and confusing.
Upvotes: 1
Views: 3291
Reputation: 38922
In raw_data
, values for a form field are collected in a list.
You want to work with data
because its value is processed to its python representation. Most fields subclassing wtforms.fields.core.Field
implements their own process_formdata
method which fulfills this.
Start by implementing a helper function that checks field data like so:
def is_filled(data):
if data == None:
return False
if data == '':
return False
if data == []:
return False
return True
Note that data starts out set to the default value if a default value is specified in the field schema. In this case using raw_data
is more correct.
def is_filled(raw_data):
try:
value = raw_data[0]
if value == '':
return False
except (IndexError, TypeError):
return False
return True
Tests:
>>> is_filled(None)
False
>>> is_filled([])
False
>>> is_filled(['',])
False
Upvotes: 2