我结合了 Flask-WTF 和 Flask-upload 来处理我的App上的文件上传。
我的软件包版本为:
Flask-Uploads==0.2.1
Flask-WTF==0.11
WTForms==2.1
这是我的代码段:
forms.py
from flask_wtf import Form
from flask_wtf.file import FileAllowed, FileRequired
from wtforms.fields import (StringField, SubmitField, FileField)
from wtforms.validators import InputRequired, Length
from app import photos
class AddCourseForm(Form):
name = StringField('Course name', validators=[InputRequired(), Length(1, 100)])
image = FileField('image', validators=[FileRequired(), FileAllowed(photos, 'Images only!')])
submit = SubmitField('Add course')
这是上传代码的片段:
@operator.route('/add-course', methods=['GET', 'POST'])
def add_course():
form = AddCourseForm()
if form.validate_on_submit():
course_name = form.name.data
filename = photos.save(request.files['image'], name="courses/" + course_name + "_course.")
course = Course(name=course_name, image=filename)
db.session.add(course)
db.session.commit()
flash('Successfully added {} '.format(course.course_name()) + 'course', 'success')
return redirect(url_for('operator.courses'))
return render_template('main/operator/add_course.html', form=form)
但是,当我提交时,出现以下错误:
AttributeError: 'FileField' object has no attribute 'has_file'
然后,我尝试通过直接传递扩展名来遵循此documentation,而没有Flask-Upload:
image = FileField('image', validators=[FileRequired(), FileAllowed(['jpg', 'png'], 'Images only!')])
但是我仍然遇到同样的错误。
那么,我的代码有什么问题呢? 请,任何帮助将不胜感激:)
答案 0 :(得分:1)
您从wtforms库导入FileField
:
from wtforms.fields import (StringField, SubmitField, FileField)
...,但是FileField.has_file()
方法特定于Flask-WTF
。
您需要将FileField
中的flask_wtf.file
添加到其他导入中。
您可以访问Flask-WTF.file.FileField
here的API文档。
当前的实现(found here)是:
class FileField(_FileField):
"""Werkzeug-aware subclass of :class:`wtforms.fields.FileField`."""
def process_formdata(self, valuelist):
valuelist = (x for x in valuelist if isinstance(x, FileStorage) and x)
data = next(valuelist, None)
if data is not None:
self.data = data
else:
self.raw_data = ()
def has_file(self):
"""Return ``True`` if ``self.data`` is a
:class:`~werkzeug.datastructures.FileStorage` object.
.. deprecated:: 0.14.1
``data`` is no longer set if the input is not a non-empty
``FileStorage``. Check ``form.data is not None`` instead.
"""
warnings.warn(FlaskWTFDeprecationWarning(
'"has_file" is deprecated and will be removed in 1.0. The data is '
'checked during processing instead.'
))
return bool(self.data)
如您所见,该类继承自标准wtforms实现(在模块中名为_FileField
),但对其进行了扩展以覆盖process_formdata()
方法并添加has_file()
方法。 / p>
还要注意,他们正在折旧该方法,建议您只检查该字段的data
属性-它不完全是技术上的实现,因此您可以执行其操作来获得相同的功能:{ {1}}。
作为参考,这是wtforms bool(field.data)
的实现:
FileField
...表明它没有除基类class FileField(Field):
"""Renders a file upload field.
By default, the value will be the filename sent in the form data.
WTForms **does not** deal with frameworks' file handling capabilities.
A WTForms extension for a framework may replace the filename value
with an object representing the uploaded data.
"""
widget = widgets.FileInput()
def _value(self):
# browser ignores value of file input for security
return False
上定义的方法之外的任何方法。