文件上传与邮件发送

# 文件上传与邮件发送

### 原生实现

- 模板文件

  ```html
  <form method="post" enctype="multipart/form-data">
      <input type="file" name="photo" /><br />
      <input type="submit" value="上传" />
  </form>
  ```

- 视图函数

  ```python
  import os

  # 配置上传文件保存目录
  app.config[‘UPLOADED_FOLDER‘] = os.path.join(os.getcwd(), ‘static/upload‘)

  @app.route(‘/upload/‘, methods=[‘GET‘, ‘POST‘])
  def upload():
      if request.method == ‘POST‘:
          # 获取上传对象
          photo = request.files.get(‘photo‘)
          if photo:
              # 拼接保存路径名
              pathname = os.path.join(app.config[‘UPLOADED_FOLDER‘], photo.filename)
              # 保存上传文件
              photo.save(pathname)
              return ‘上传成功‘
          else:
              return ‘上传失败‘
      return render_template(‘upload.html‘)
  ```

- 上传限制设置

  ```python
  # 允许上传的文件后缀
  ALLOWED_SUFFIX = set([‘png‘, ‘jpg‘, ‘jpeg‘, ‘gif‘])

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

  # 限制请求大小
  app.config[‘MAX_CONTENT_LENGTH‘] = 1024 * 1024 * 8

  # 展示上传的图片
  @app.route(‘/uploaded/<filename>‘)
  def uploaded(filename):
      return send_from_directory(app.config[‘UPLOADED_FOLDER‘], filename)

  @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):
              # 拼接保存路径名
              pathname = os.path.join(app.config[‘UPLOADED_FOLDER‘], photo.filename)
              # 保存上传文件
              photo.save(pathname)
              # 构造上传文件的url
              img_url = url_for(‘uploaded‘, filename=photo.filename)
      return render_template(‘upload.html‘, img_url=img_url)
  ```

### flask-uploads

- 说明:极大的的简化了文件上传相关的操作,使用非常方面。

- 安装:`pip install flask-uploads`

- 使用:

  - 配置

  ```python
  from flask_uploads import UploadSet, IMAGES
  from flask_uploads import configure_uploads
  from flask_uploads import patch_request_class
  import os

  app.config[‘UPLOADED_PHOTOS_DEST‘] = os.getcwd()
  app.config[‘MAX_CONTENT_LENGTH‘] = 8 * 1024 * 1024
  # 创建上传对象
  photos = UploadSet(‘photos‘, IMAGES)
  # 配置上传对象
  configure_uploads(app, photos)
  # 配置上传文件大小,默认为64M,
  # 若设置为None,则以MAX_CONTENT_LENGTH配置为准
  patch_request_class(app, size=None)
  ```

  - 视图函数

  ```python
  @app.route(‘/upload/‘, methods=[‘GET‘, ‘POST‘])
  def upload():
      img_url = None
      if request.method == ‘POST‘:
          # 获取上传对象
          photo = request.files.get(‘photo‘)
          if photo:
              # 保存上传文件,返回文件名
              filename = photos.save(photo)
              # 根据文件名获取上传文件的URL
              img_url = photos.url(filename)
      return render_template(‘upload.html‘, img_url=img_url)
  ```

### 综合使用

- 要求:结合flask-bootstrap、flask-wtf、flask-uploads等完成文件上传

- 使用:

  - 配置

  ```python
  from flask_wtf import FlaskForm
  from flask_wtf.file import FileField, FileAllowed, FileRequired
  from wtforms import SubmitField
  from flask_uploads import UploadSet, IMAGES
  from flask_uploads import configure_uploads
  from flask_uploads import patch_request_class
  from flask_bootstrap import Bootstrap
  import os

  bootstrap = Bootstrap(app)

  app.config[‘SECRET_KEY‘] = ‘123456‘
  app.config[‘MAX_CONTENT_LENGTH‘] = 8 * 1024 * 1024
  app.config[‘UPLOADED_PHOTOS_DEST‘] = os.path.join(os.getcwd(), ‘static/upload‘)

  photos = UploadSet(‘photos‘, IMAGES)
  configure_uploads(app, photos)
  patch_request_class(app, size=None)

  class UploadForm(FlaskForm):
      photo = FileField(‘头像‘, validators=[FileRequired(message=‘请选择文件‘),
                                          FileAllowed(photos, message=‘只能上传图片文件‘)])
      submit = SubmitField(‘上传‘)
  ```

  - 视图函数

  ```python
  @app.route(‘/upload/‘, methods=[‘GET‘, ‘POST‘])
  def upload():
      img_url = None
      form = UploadForm()
      if form.validate_on_submit():
          photo = form.photo.data
          filename = photos.save(photo)
          img_url = photos.url(filename)
      return render_template(‘upload.html‘, form=form, img_url=img_url)
  ```

  - 模板文件

  ```html
  {% extends ‘bootstrap/base.html‘ %}

  {% from ‘bootstrap/wtf.html‘ import quick_form %}

  {% block title %}完整的文件上传{% endblock %}

  {% block content %}
      <div class="container">
          {% if img_url %}
              <img src="{{ img_url }}">
          {% endif %}
          {{ quick_form(form) }}
      </div>
  {% endblock %}
  ```

  - 生成随机文件名

  ```python
  def random_string(length=32):
      import random
      base_str = ‘abcdefghijklmnopqrstuvwxyz1234567890‘
      return ‘‘.join(random.choice(base_str) for i in range(length))

  @app.route(‘/upload/‘, methods=[‘GET‘, ‘POST‘])
  def upload():
      。。。
          # 提取文件后缀
          suffix = os.path.splitext(photo.filename)[1]
          # 生成随机文件名
          filename = random_string() + suffix
          # 保存文件
          photos.save(photo, name=filename)
      。。。
  ```

  - 生成缩略图:PIL模块(只支持py2,要支持py3需要安装pillow)

  ```python
  from PIL import Image

  @app.route(‘/upload/‘, methods=[‘GET‘, ‘POST‘])
  def upload():
      ...
          # 拼接完整文件路径名
          pathname = os.path.join(app.config[‘UPLOADED_PHOTOS_DEST‘], filename)
          # 打开文件
          img = Image.open(pathname)
          # 设置大小
          img.thumbnail((64, 64))
          # 保存图片
          img.save(pathname)
      ...
  ```

### flask-mail

- 说明:专门用于邮件发送的扩展库,使用非常方便。

- 安装:`pip install flask-mail`

- 使用:

  ```python
  from flask_mail import Mail, Message
  import os

  # 邮件发送配置,一定要放在创建Mail对象之前
  app.config[‘MAIL_SERVER‘] = ‘smtp.1000phone.com‘
  # 用户名
  app.config[‘MAIL_USERNAME‘] = ‘[email protected]‘
  # 密码
  app.config[‘MAIL_PASSWORD‘] = os.getenv(‘MAIL_PASSWORD‘, ‘123456‘)

  # 创建发送邮件的对象
  mail = Mail(app)

  @app.route(‘/send/‘)
  def send():
      # 创建邮件消息对象
      msg = Message(‘账户激活‘,
                    recipients=[‘[email protected]‘],
                    sender=app.config[‘MAIL_USERNAME‘])
      msg.html = ‘恭喜你,中奖了!!!‘
      # 发送邮件
      mail.send(msg)
      return ‘邮件已发送‘
  ```

- 封装函数发送邮件

  ```python
  def send_mail(subject, to, template, *args, **kwargs):
      if isinstance(to, list):
          recipients = to
      elif isinstance(to, str):
          recipients = to.split(‘,‘)
      else:
          raise Exception(‘邮件接收者参数类型有误‘)
      # 创建邮件消息对象
      msg = Message(subject,
                    recipients=recipients,
                    sender=app.config[‘MAIL_USERNAME‘])
      # 将邮件模板渲染后作为邮件内容
      msg.html = render_template(template, *args, **kwargs)
      # 发送邮件
      mail.send(msg)
  ```

- 异步发送邮件

  ```python
  from flask import current_app

  # 异步发送邮件任务
  def async_send_mail(app, msg):
      # 邮件发送必须在程序上下文
      # 新的线程中没有上下文,因此需要手动创建
      with app.app_context():
          mail.send(msg)

  # 封装函数发送邮件
  def send_mail(subject, to, template, *args, **kwargs):
      if isinstance(to, list):
          recipients = to
      elif isinstance(to, str):
          recipients = to.split(‘,‘)
      else:
          raise Exception(‘邮件接收者参数类型有误‘)
      # 创建邮件消息对象
      msg = Message(subject,
                    recipients=recipients,
                    sender=app.config[‘MAIL_USERNAME‘])
      # 将邮件模板渲染后作为邮件内容
      msg.html = render_template(template, *args, **kwargs)
      # 异步发送邮件
      # current_app是app的代理对象
      # 根据代理对象current_app找到原始的app
      app = current_app._get_current_object()
      # 创建线程
      thr = Thread(target=async_send_mail, args=(app, msg))
      # 启动线程
      thr.start()
      # 返回线程
      return thr
  ```

###环境变量

- windows:
  - 设置:`set 环境变量名=值`
  - 获取:`set 环境变量名`
- linux:
  - 导出:`export 环境变量名=值`
  - 获取:`echo $环境变量名`
- 代码:
  - `os.getenv(‘环境变量名‘, ‘123456‘)`

原文地址:https://www.cnblogs.com/liangliangzz/p/10221980.html

时间: 2024-08-25 11:38:33

文件上传与邮件发送的相关文章

[iOS 多线程 &amp; 网络 - 2.5] - 小文件上传

A.文件上传 思路: 发送文件数据给服务器 使用post请求 必须手动设置请求头: 内容大小Content-Length & 内容类型 Content-Type 请求体:文件数据 文件上传的格式要求十分严格,必须严格遵守 由于是一次性加载文件到内存上传,所以只能用于小文件上传 B.实现 1.设置POST请求 (1)使用POST请求方法 (2)设置请求头 设置内容长度.内容类型.分割线 (3)设置请求体 NSMutableData *body = [NSMutableData data]; 分割线

iOS多线程与网络开发之小文件上传

郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 游戏官方下载:http://dwz.cn/RwTjl 游戏视频预览:http://dwz.cn/RzHHd 游戏开发博客:http://dwz.cn/RzJzI 游戏源代码传送:http://dwz.cn/Nret1 A.文件上传 思路: 发送文件数据给server 使用post请求 必须手动设置请求头: 内

关于 PHPMailer 邮件发送类的使用心得(含多文件上传)

Is this important for send mail PHPMailer 核心文件 class.phpmailer.php class.phpmaileroauth.php class.phpmaileroauthgoogle.php class.pop3.php class.smtp.php get_oauth_token.php PHPMailerAutoload.php 在使用PHPMailer之前,首先查看PHP环境扩展中是否开启了socket 和openssl扩展,如若没有开

JavaWeb之文件上传与下载&amp;邮件技术(十八)

文件上传 简介 最近发现这几篇很少写简介,说自己没时间写,可能是说服自己吧.总之能多写就多写.还有个一直存在的问题,每天写的博客质量不是很好.再次说服自己,现在处于学习阶段,写博客为了巩固知识点,以便后期作复习使用.其实我每次写博客之前笔记老早都在nopad++上写好了,所以大部分在wlw上直接粘贴的,请见谅 1. 文件上传必要前提 1. form表单:属性enctype必须取值为multipart/form-data enctype的默认值是:application/x-www-form-ur

WebApi发送HTML表单数据:文件上传与多部分MIME

5.3 Sending HTML Form Data5.3 发送HTML表单数据(2) 本文引自:http://www.cnblogs.com/r01cn/archive/2012/12/20/2826230.html By Mike Wasson|June 21, 2012作者:Mike Wasson | 日期:2012-6-21 Part 2: File Upload and Multipart MIME第2部分:文件上传与多部分MIME This tutorial shows how to

(转)WebApi发送HTML表单数据:文件上传与多部分MIME

5.3 Sending HTML Form Data5.3 发送HTML表单数据(2) 本文引自:http://www.cnblogs.com/r01cn/archive/2012/12/20/2826230.html By Mike Wasson|June 21, 2012作者:Mike Wasson | 日期:2012-6-21 Part 2: File Upload and Multipart MIME第2部分:文件上传与多部分MIME This tutorial shows how to

使用HttpClient 发送 GET、POST(FormData、Raw)、PUT、Delete请求及文件上传

httpclient4.3.6 package org.caeit.cloud.dev.util; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; import java.util.Map;

【原创】用JAVA实现大文件上传及显示进度信息

用JAVA实现大文件上传及显示进度信息 ---解析HTTP MultiPart协议 一. 大文件上传基础描述: 各种WEB框架中,对于浏览器上传文件的请求,都有自己的处理对象负责对Http MultiPart协议内容进行解析,并供开发人员调用请求的表单内容. 比如: Spring 框架中使用类似CommonsMultipartFile对象处理表二进制文件信息. 而.NET 中使用HtmlInputFile/ HttpPostedFile对象处理二进制文件信息. 优点:使用框架内置对象可以很方便的

HTML5开发 拖拽文件上传

Drag&Drop 拖拽功能的处理 关于HTML5拖拽文件上传,其实国外已经有很多网站有这样的应用,最早推出拖拽上传应用的是 Gmail,它支持标准浏览器下拖拽本地文件到浏览器中作为邮件的附件发送,但其实现在利用HTML5的功能实现,主要借助于新版支持的浏览器来实现,IE还是弱很多. 拖拽上传应用主要使用了以下 HTML5技术: Drag&Drop : HTML5基于拖拽的事件机制.File API : 可以很方便的让 Web 应用访问文件对象,File API 包括FileList.Bl