Linux运维知识之Flask学习4:文件上传与邮件发送
小标 2019-04-15 来源 : 阅读 1096 评论 0

摘要:本文主要向大家介绍了Linux运维知识之Flask学习4:文件上传与邮件发送,通过具体的内容向大家展现,希望对大家学习Linux运维知识有所帮助。

本文主要向大家介绍了Linux运维知识之Flask学习4:文件上传与邮件发送,通过具体的内容向大家展现,希望对大家学习Linux运维知识有所帮助。

Linux运维知识之Flask学习4:文件上传与邮件发送

文件上传与邮件发送


原生上传文件


1.添加一个模板文件html


<!DOCTYPE html>
<html>
<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>
<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

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注系统运维Linux频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程