您的位置:首页 > 其它

Flask学习4:文件上传与邮件发送

2017-12-27 17:16 561 查看

文件上传与邮件发送

原生上传文件

1.添加一个模板文件html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
{% if img_url %}
<img src="{{ img_url }}">
{% endif %}
<form method="post" enctype="multipart/form-data">
<input type="file" name="photo">
<input type="submit" value="上传">
</form>
</body>
</html>


2.添加视图函数

@app.route('/upload/', methods=['GET', 'POST'])
def upload():
img_url = None
if request.method == 'POST':
photo = request.files.get('photo')
if photo and allowed_file(photo.filename):
# 获取文件后缀
suffix = os.path.splitext(photo.filename)[-1]

# 随机生成文件名
photoname = random_string() + suffix
# 保存上传的文件
photo.save(os.path.join(app.config['UPLOAD_FOLDER'], photoname))

img_url = url_for('uploaded', filename=photoname)
return render_template('upload.html', img_url = img_url)


3.相关配置及函数

# 允许上传的文件后缀
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])

# 配置上传文件的保存位置
app.config['UPLOAD_FOLDER'] = os.getcwd()

# 限制上传文件大小
app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024 * 8

# 判断是否是允许的文件后缀
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS

# 获取上传文件的url
@app.route('/uploaded/<filename>')
def uploaded(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'], filename)

# 生成随机字符串
def random_string(length = 32):
import random
base_str = 'abcdefghijklmnopqrstuvwxyz1234567890'
return ''.join([random.choice(base_str) for i in range(length)])


4.注意事项,文件上传失败时,应从哪些方面着手

1.表单的提交方法必须是POST
2.表单的enctype属性必须设置(multipart/form-data)
3.上传的字段类型必须为file, 并且必须有name属性
4.是否超过了允许的最大尺寸
5.文件的保存位置是否还有空间,是否有权限


5.生成缩略图(需要安装Pillow库)

# 保存上传的文件
photo.save(pathname)

# 生成缩略图
# 1.打开文件
img = Image.open(pathname)
# 2.重新设置尺寸
img.thumbnail((128, 128))  # 参数为元组,指定宽高
# 3.保存修改
img.save(pathname)


扩展

环境变量:好处是可以避免隐私信息公布于众(设置时注意等号两边不要加空格)。

windows配置

设置:set NAME=dandan
获取:set NAME


linux配置

导出:export NAME=dandan
获取:echo $NAME


代码获取

@app.route('/env/')
def env():
return os.environ.get('NAME', 'Ahh')


flask-uploads

1.说明

​ 在文件上传时,提供了很大的方便,比如文件类型的过滤、校验等

2.安装

pip install flask-upload


3.使用

from flask_uploads import UploadSet, IMAGES, configure_uploads, patch_request_class

# 上传文件的大小

app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024 * 8

# 上传文件的保存位置

import os
app.config['UPLOADED_PHOTOS_DEST'] = os.getcwd()

# 创建上传对象, 需要指定过滤的文件后缀

photos = UploadSet('photos', IMAGES)
configure_uploads(app, photos)

# 配置上传文件大小, 默认64M,设置为None时使用MAX_CONTENT_LENGTH的大小

patch_request_class(app, size=None)

@app.route('/upload/', methods=['GET', 'POST'])
def upload():
img_url = None
if request.method == 'POST' and 'photo' in request.files:
# 保存文件
filename = photos.save(request.files['photo'])

# 获取保存文件的url
img_url = photos.url(filename)
return render_template('upload.html', img_url = img_url)

# html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>文件上传</title> </head> <body> {% if img_url %} <img src="{{ img_url }}"> {% endif %} <form method="post" enctype="multipart/form-data"> <input type="file" name="photo"> <input type="submit" value="上传"> </form> </body> </html>


完整的文件上传

1.flask-uploads配置同上

2.flask-wtf配置

# 导入表单基类

from flask_wtf import FlaskForm

# 导入文件上传字段及验证器

from flask_wtf.file import FileField, FileRequired, FileAllowed
from wtforms import SubmitField

# 上传文件表单类

class UploadForm(FlaskForm):
photo = FileField('头像上传', validators=[FileRequired('文件未选择'), FileAllowed(photos, message='文件类型错误')])
submit = SubmitField('上传')


3.视图函数

# 随机生成文件名

def random_string(length = 32):
import random
base_str = '1234567890qwertyuiopasdfghjklmnbvcxz'
return ''.join([random.choice(base_str) for i in range(length)])

@app.route('/upload/', methods=['GET', 'POST'])
def upload():
img_url = None
form = UploadForm()
if form.validate_on_submit():
# 获取文件后缀
suffix = os.path.splitext(form.photo.data.filename)[1]
filename = random_string() + suffix

# 保存上传文件
photos.save(form.photo.data, name=filename)

# 生成缩略图
pathname = os.path.join(app.config['UPLOADED_PHOTOS_DEST'], filename)
# 打开文件
img = Image.open(pathname)

# 设置尺寸
img.thumbnail((128, 128))

img.save(pathname)

img_url = photos.url(filename)
return render_template('upload2.html', form=form, img_url=img_url)


4.模板文件

{% extends 'bootstrap/base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}

{% block content %}
<div class="container">
{% if img_url %}
<img src="{{ img_url }}">
{% endif %}

{{ wtf.quick_form(form) }}
</div>
{% endblock %}


flask-mail

1.说明

​ 是一个邮件发送的扩展库,使用非常方便

2.安装

pip install flask-mail


3.配置

from flask_mail import Mail, Message

# 配置一定要写在创建Mail对象之前,否则不起作用

# 邮箱服务器

import os
app.config['MAIL_SERVER'] = os.environ.get('MAIL_SERVER', 'smtp.163.com')

# 用户名

app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME', 'xxx@163.com')

# 密码,密码有时是授权码

app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD', 'xxxxxx')

# 创建对象

mail = Mail(app)


4.发送邮件

@app.route('/')
def hello_world():
# 创建邮件对象
msg = Message(subject='丹丹的测试邮件', recipients=['xxx@qq.com'], sender=app.config['MAIL_USERNAME'])
# 浏览器打开显示这个
msg.html = '<h1>Nice day</h1>'
# 终端打开显示这个
msg.body = 'Body'
mail.send(msg)
return '邮件已发送!'


5.封装函数,发送邮件

# 封装函数,发送邮件

def send_mail(to, subject, template, **kwargs):
# 创建邮件对象
msg = Message(subject=subject, recipients=to, sender=app.config['MAIL_USERNAME'])
# 浏览器打开显示这个
msg.html = '<b>Nice day</b>'
# 终端打开显示这个
msg.body = 'Nice day'
mail.send(msg)


6.异步发送邮件

# 异步发送邮件

def async_send_mail(app, msg):
# 发送邮件需要程序上下文,新的线程中没有上下文,需要手动创建
with app.app_context():
# 发送邮件
mail.send(msg)

# 封装函数,发送邮件

def send_mail(to, subject, template, **kwargs):
# 根据current_app获取当前实例
app = current_app._get_current_object()
# 创建邮件对象
msg = Message(subject=subject, recipients=to, sender=app.config['MAIL_USERNAME'])
# 浏览器打开显示这个
msg.html = render_template(template + '.html', **kwargs)
# 终端打开显示这个
msg.body = render_template(template + '.txt', **kwargs)
# mail.send(msg)

# 创建线程
thr = Thread(target=async_send_mail, args=[current_app, msg])
# 启动线程
thr.start()
return thr


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  邮件 flask-web