Flask 和 WTForms - 如何确定文件上传字段是否已提交用于处理目的
Flask and WTForms - How to determine if File Upload field is submitted for processing purposes
我创建了一个带有可选 WTForms 文件字段的表单来上传文件。表单有效...但是提交后,我的 view.py 代码总是尝试处理上传的文件,无论它是否已提交。
如何确定文件是否已上传?我希望我的代码仅在上传内容时才处理上传。
现在,我还没有找到正确的验证方法,所以我的代码正在处理上传的文件,即使没有文件上传。
我目前正在 views.py 中尝试进行区分,但它不起作用(见下文):
attachFile = False
if attachment:
attachFile = True
我也尝试了以下方法来实现某些事情(这些在 views.py 中的完整代码中被注释掉了):
First attempt: if form.attachment.data is not str:
Second attempt: if not attachment.filename == "":
Third attempt: if (isinstance(attachment,str) == False):
(Fourth (and current) attempt is above)
我也尝试过以下方法,但在未上传文件时出现以下错误:
if attachment.data:
attachFile = True
## AttributeError: 'str' object has no attribute 'data'
forms.py:
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField,
SubmitField, TextAreaField, FileField
from wtforms.fields.html5 import EmailField
from wtforms.validators import DataRequired, Email
class MailerForm(FlaskForm):
fromName = StringField('fromName', validators=[DataRequired()])
fromEmail = EmailField('fromEmail', validators=[DataRequired(), Email()])
subject = StringField('Subject', validators=[DataRequired()])
toAddress = TextAreaField('toAddress', validators=[DataRequired()])
message = TextAreaField('message', validators=[DataRequired()])
attachment = FileField('attachment')
submit = SubmitField('Send Email')
views.py
@app.route('/mailer/', methods=['GET','POST'])
def mailer():
# compiled regex to quick and dirty email validation
EMAIL_REGEX = re.compile(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)")
form = MailerForm()
if form.validate_on_submit():
fromName = form.fromName.data
fromEmail = form.fromEmail.data
subject = form.subject.data
toAddress = form.toAddress.data
messageBody = form.message.data
attachment = form.attachment.data
newFileName = ""
attachFile = False
if attachment:
attachFile = True
basedir = os.path.abspath(os.path.dirname(__file__))
## lists to track successful and unsuccessful email addresses submitted
success = []
failure = []
##
## split email address
##
addresses = toAddress.split("\n")
##
## iterate through email addresses, validate, and send
##
for address in addresses:
address = address.strip()
if EMAIL_REGEX.match(address):
##if (isinstance(attachment,str) == False):
##if not attachment.filename == "":
if attachFile == True:
filename = os.path.join(basedir + "/static/" + app.config['UPLOAD_FOLDER'], attachment.filename)
attachment.save(filename)
msg = Message(subject)
msg.sender = (fromName,fromEmail)
msg.recipients = [address]
msg.body = messageBody
#if form.attachment.data is not str:
#if not attachment.filename == "":
#if (isinstance(attachment,str) == False):
if attachFile == True:
newFileName = attachment.filename
with app.open_resource(filename) as fp:
msg.attach(
newFileName,
"application/octet-stream",
fp.read())
mail.send(msg)
success.append(address)
else:
failure.append(address)
print("Failed:" + address)
else:
"""Renders index page."""
return render_template(
'mailer/mailer.html',
form = form
)
##
## Successfully emailed, time to nuke the temp attachment
##
os.system('rm ' + basedir + "/static/" + app.config['UPLOAD_FOLDER'] + "/'" + newFileName + "'")
##
##
##
return render_template(
'mailer/mailerCompleted.html',
form = form,
success = success,
failure = failure
)
将 FileRequired() 添加到验证器:
from flask_wtf.file import FileField, FileRequired
...
attachment = FileField('attachment' , validators=[FileRequired()])
需要文件,如果不提交文件,表单将无法验证。
编辑:
如果您希望文件是可选的,请删除 validators=[FileRequired()]
并检查文件是否已通过:
if form.attachment.data is None:
print("File is empty")
# Code if file is empty
else:
# Code if file is passed
你也可以使用not
:
if not form.attachment.data:
print('no files has been uploaded')
当 A 为空或 None
. 时,not A
为 true
所以,它在没有附加文件时触发(form.attachment.data == None
)
使用 Flask-WTF==0.14.3,wtforms==2.3.3
is None
测试无效。 ==''
测试有效。
使用 FileField 的表单定义
class ProfileForm(FlaskForm):
# other fields
photo = FileField('Profile photo')
提交表单时
def profile():
form = ProfileForm()
if form.validate_on_submit():
print('form.photo.data: [{}]'.format(form.photo.data))
print('is None test: [{}]'.format(form.photo.data is None))
print('==\'\' test: [{}]'.format(form.photo.data == ''))
if form.photo.data is None:
# will NOT work
flash('you should upload a profile photo')
if form.photo.data == '':
# will work
flash('profile photo is highly recommended')
return render_template('profile.html', form=form)
我创建了一个带有可选 WTForms 文件字段的表单来上传文件。表单有效...但是提交后,我的 view.py 代码总是尝试处理上传的文件,无论它是否已提交。
如何确定文件是否已上传?我希望我的代码仅在上传内容时才处理上传。
现在,我还没有找到正确的验证方法,所以我的代码正在处理上传的文件,即使没有文件上传。
我目前正在 views.py 中尝试进行区分,但它不起作用(见下文):
attachFile = False
if attachment:
attachFile = True
我也尝试了以下方法来实现某些事情(这些在 views.py 中的完整代码中被注释掉了):
First attempt: if form.attachment.data is not str:
Second attempt: if not attachment.filename == "":
Third attempt: if (isinstance(attachment,str) == False):
(Fourth (and current) attempt is above)
我也尝试过以下方法,但在未上传文件时出现以下错误:
if attachment.data:
attachFile = True
## AttributeError: 'str' object has no attribute 'data'
forms.py:
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField,
SubmitField, TextAreaField, FileField
from wtforms.fields.html5 import EmailField
from wtforms.validators import DataRequired, Email
class MailerForm(FlaskForm):
fromName = StringField('fromName', validators=[DataRequired()])
fromEmail = EmailField('fromEmail', validators=[DataRequired(), Email()])
subject = StringField('Subject', validators=[DataRequired()])
toAddress = TextAreaField('toAddress', validators=[DataRequired()])
message = TextAreaField('message', validators=[DataRequired()])
attachment = FileField('attachment')
submit = SubmitField('Send Email')
views.py
@app.route('/mailer/', methods=['GET','POST'])
def mailer():
# compiled regex to quick and dirty email validation
EMAIL_REGEX = re.compile(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)")
form = MailerForm()
if form.validate_on_submit():
fromName = form.fromName.data
fromEmail = form.fromEmail.data
subject = form.subject.data
toAddress = form.toAddress.data
messageBody = form.message.data
attachment = form.attachment.data
newFileName = ""
attachFile = False
if attachment:
attachFile = True
basedir = os.path.abspath(os.path.dirname(__file__))
## lists to track successful and unsuccessful email addresses submitted
success = []
failure = []
##
## split email address
##
addresses = toAddress.split("\n")
##
## iterate through email addresses, validate, and send
##
for address in addresses:
address = address.strip()
if EMAIL_REGEX.match(address):
##if (isinstance(attachment,str) == False):
##if not attachment.filename == "":
if attachFile == True:
filename = os.path.join(basedir + "/static/" + app.config['UPLOAD_FOLDER'], attachment.filename)
attachment.save(filename)
msg = Message(subject)
msg.sender = (fromName,fromEmail)
msg.recipients = [address]
msg.body = messageBody
#if form.attachment.data is not str:
#if not attachment.filename == "":
#if (isinstance(attachment,str) == False):
if attachFile == True:
newFileName = attachment.filename
with app.open_resource(filename) as fp:
msg.attach(
newFileName,
"application/octet-stream",
fp.read())
mail.send(msg)
success.append(address)
else:
failure.append(address)
print("Failed:" + address)
else:
"""Renders index page."""
return render_template(
'mailer/mailer.html',
form = form
)
##
## Successfully emailed, time to nuke the temp attachment
##
os.system('rm ' + basedir + "/static/" + app.config['UPLOAD_FOLDER'] + "/'" + newFileName + "'")
##
##
##
return render_template(
'mailer/mailerCompleted.html',
form = form,
success = success,
failure = failure
)
将 FileRequired() 添加到验证器:
from flask_wtf.file import FileField, FileRequired
...
attachment = FileField('attachment' , validators=[FileRequired()])
需要文件,如果不提交文件,表单将无法验证。
编辑:
如果您希望文件是可选的,请删除 validators=[FileRequired()]
并检查文件是否已通过:
if form.attachment.data is None:
print("File is empty")
# Code if file is empty
else:
# Code if file is passed
你也可以使用not
:
if not form.attachment.data:
print('no files has been uploaded')
当 A 为空或 None
. 时,not A
为 true
所以,它在没有附加文件时触发(form.attachment.data == None
)
使用 Flask-WTF==0.14.3,wtforms==2.3.3
is None
测试无效。 ==''
测试有效。
使用 FileField 的表单定义
class ProfileForm(FlaskForm):
# other fields
photo = FileField('Profile photo')
提交表单时
def profile():
form = ProfileForm()
if form.validate_on_submit():
print('form.photo.data: [{}]'.format(form.photo.data))
print('is None test: [{}]'.format(form.photo.data is None))
print('==\'\' test: [{}]'.format(form.photo.data == ''))
if form.photo.data is None:
# will NOT work
flash('you should upload a profile photo')
if form.photo.data == '':
# will work
flash('profile photo is highly recommended')
return render_template('profile.html', form=form)