Rapolas K.
Rapolas K.

Reputation: 1709

Validating FileField using wtforms

I'm trying to validate FileField field from wtforms, however, I get the following exception, when file is selected:

File "forms.py", line 15, in check_cover # my forms.py file with custom validator
  if field.data:
File "/usr/lib/python3.3/cgi.py", line 637, in __len__
  return len(self.keys())
File "/usr/lib/python3.3/cgi.py", line 626, in keys
  raise TypeError("not indexable")

Validator code and form itself:

def check_cover(form, field):
  if field.data: # this line raises exception
    filename = field.data.filename
    ext = os.path.splitext(filename)[1].strip(".")
    if not ext.lower() in ALLOWED_IMG_EXT:
        raise validators.ValidationError('Has to be an image')
  else:
    raise validators.ValidationError('Please, provide an image')

class BlogPostForm(Form):
  title = TextField('Title',
                    validators=[validators.Length(min=1, max=200)])
  content = TextAreaField('Content', [validators.Length(min=1)],
                          id='blog-content')
  cover_pic = FileField('Cover image', validators=[check_cover])

And html form:

<form method="POST" action="save" enctype="multipart/form-data">
  {{ form.title }}
  {{ form.content }}
  {{ form.cover_pic }}
  <input type="submit" value="Save" />
</form>

Validator works for the case, when file is not selected, but as soon as I select a file, it fails on that check. I could try to access filename, instead of just data (field.data.filename) and it works fine, but only if a file is actually selected. If no file is selected it fails with AttributeError: 'bytes' object has no attribute 'value'. So that is understandable.

Could it be due to the fact that I'm using python3? How can I solve this issue?

Thanks,
Rapolas

Upvotes: 4

Views: 2835

Answers (1)

Hern&#225;n Acosta
Hern&#225;n Acosta

Reputation: 695

First, you should check if a file is selected:

if type(form.cover_pic.data) is not UnicodeType:

Also, you have an error using strip method instead of split:

ext = os.path.splitext(filename)[1].strip(".")

Upvotes: 2

Related Questions