Flask 上传自定义头像

Flask Web 开发这本书基本上做完了,后面还需要温习,但是自己做的博客总觉得简陋了点,所以,在动脑子开发新功能

今天想到最基本的功能,自定义头像

那这样的功能,设计到2大基本功能块

1:如何进行文件的上传和保存

2:如何在用户模型里面将头像照片和用户挂钩起来


第二个问题我在查阅了网上的讨论后,得出基本上2种方法,

第一种是将图片变成二进制以后存入数据库

第二种是将图片直接存放于文件系统中


先研究如何上传文件成功这个事情

从最简单的开始

在main的views文件内,添加以下准备工作

[python]  view plain  copy
  1. import os  
  2. from flask import Flask, request, redirect, url_for  
  3.   
  4. UPLOAD_FOLDER=r'E:\flasky\app\upload'  

设置UPLOAD_FOLDER的路径,表示文件最终要存在哪一个位置


[python]  view plain  copy
  1. @main.route('/upload_file',methods = ['GET','POST'])  
  2. def upload_file():  
  3.   
  4. #...  
  5.     if request.method == 'POST':  
  6.         file = request.files['file']  
  7.         file.save(os.path.join(UPLOAD_FOLDER,file.filename))  
  8.         return '<p>success</p>'  
  9.     return ''''' 
  10.     <!DOCTYPE html> 
  11.     <title>Change new icon</title> 
  12.     <h1>Upload new </h1> 
  13.     <form action = "" method = "post" enctype=multipart/form-data> 
  14.         <input type = "file" name = file> 
  15.         <input type = "submit" value = Upload> 
  16.     </form> 
  17.     '''  


然后为上传文件功能单独做一个路由,是专门用一个页面来提供上传文件

file=request.files['file']表示,从request请求的files字典中,取出file对应的文件。这个文件是一个FileStorage对象,这个我们后面再讲

这个文件对象拥有一个函数功能来保存文件,叫做save()

这个文件对象还拥有一个属性来提取文件名,叫做filename

他的参数就是路径名称

如上面代码,我用了os.path.join拼接的方法来做出保存路径名

至于提交保存以后的返回页面,我先简单做了一个 显示 success的页面表示功能成功

而整个页面的渲染,直接在return里面写入了这个表单,我们来看看功能

PS: 在用户资料页面,我已经加入了按钮来通向更改头像的页面,这个就不多说了










好,最重要的一环节上传文件已经完成了,接下来的工作就是对代码的完善了

比如,添加指定允许文件类型的范围

[python]  view plain  copy
  1. ALLOWED_EXTENSIONS=set(['txt','pdf','png','jpg','jpeg','gif'])  

于是乎,代码变成了

[python]  view plain  copy
  1. UPLOAD_FOLDER=r'E:\flasky\app\upload'  
  2. ALLOWED_EXTENSIONS=set(['txt','pdf','png','jpg','jpeg','gif'])  
  3.   
  4. def allowed_file(filename):  
  5.     return '.' in filename and filename.rsplit('.',1)[1in ALLOWED_EXTENSIONS  
  6.  
  7. @main.route('/upload_file',methods = ['GET','POST'])  
  8. def upload_file():  
  9.     if request.method == 'POST':  
  10.         file = request.files['file']  
  11.         if file and allowed_file(file.filename):  
  12.             file.save(os.path.join(UPLOAD_FOLDER,file.filename))  
  13.             return '<p>success</p>'  
  14.         return '<p> 你上传了不允许的文件类型 </p>'  
  15.     return ''''' 
  16.     <!DOCTYPE html> 
  17.     <title>Change new icon</title> 
  18.     <h1>Upload new </h1> 
  19.     <form action = "" method = "post" enctype=multipart/form-data> 
  20.         <input type = "file" name = file> 
  21.         <input type = "submit" value = Upload> 
  22.     </form> 
  23.     '''  


好,讲到这里,就要回过头来看看Flask官方文档的说明了

首先第一点,request的files属性


也就是说,files是一个MultiDict的形式,而里面的每个文件,都是一个FileStorage对象

那我们再来看下FileStorage的说明



所以说,非常方便,可以通过file.filename ,直接获取文件的名字

另外,这个文件对象,可以直接用save功能储存,2可以有2个参数,一个是dst表示存放路径,第二个是缓存尺寸,表示在存储过程中的大小,默认16kb。

我们来看下效果,我们用MP3后缀名的文件来进行测试

我在检测到是不允许的文件类型时,返回写了一句提示




接着,我们要再讲一个功能 secure_filename(),他是防止用于起一些可以影响到系统运行的文件名,来扰乱你的网站

比如如官方文档所说的



再来看下这个函数的功能,其实他为了保证文件名不会影响到系统,他就把文件名里面的斜杠和空格,替换成了下划线

这样,就保证了文件只会在当前目录使用,而不会由于路径问题被利用去做其他事情。



所以,在储存文件之前,通过这个函数把文件名先修改一下

[python]  view plain  copy
  1. @main.route('/upload_file',methods = ['GET','POST'])  
  2. def upload_file():  
  3.     if request.method == 'POST':  
  4.         file = request.files['file']  
  5.         if file and allowed_file(file.filename):  
  6.             filename = secure_filename(file.filename)  
  7.             file.save(os.path.join(UPLOAD_FOLDER,filename))  
  8.             return '<p>success</p>'  
  9.         return '<p> 你上传了不允许的文件类型 </p>'  
  10.     return ''''' 
  11.     <!DOCTYPE html> 
  12.     <title>Change new icon</title> 
  13.     <h1>Upload new </h1> 
  14.     <form action = "" method = "post" enctype=multipart/form-data> 
  15.         <input type = "file" name = file> 
  16.         <input type = "submit" value = Upload> 
  17.     </form> 
  18.     '''  


我们再来测试下功能





最后,还有一个功能,就是立即查看已经刚刚上传的文件

我这里创建了一个jpg图像文件

这里需要用到的函数是send_from_directory


我们将上传的代码再次修改一下,变成上传完以后立刻预览

[python]  view plain  copy
  1. UPLOAD_FOLDER=r'E:\flasky\app\upload'  
  2. ALLOWED_EXTENSIONS=set(['txt','pdf','png','jpg','jpeg','gif'])  
  3.   
  4. def allowed_file(filename):  
  5.     return '.' in filename and filename.rsplit('.',1)[1in ALLOWED_EXTENSIONS  
  6.  
  7. @main.route('/upload_file',methods = ['GET','POST'])  
  8. def upload_file():  
  9.     if request.method == 'POST':  
  10.         file = request.files['file']  
  11.         if file and allowed_file(file.filename):  
  12.             filename = secure_filename(file.filename)  
  13.             file.save(os.path.join(UPLOAD_FOLDER,filename))  
  14.             return redirect(url_for('.uploaded_file',filename=filename))       #跳转到预览页面  
  15.         return '<p> 你上传了不允许的文件类型 </p>'  
  16.     return ''''' 
  17.     <!DOCTYPE html> 
  18.     <title>Change new icon</title> 
  19.     <h1>Upload new </h1> 
  20.     <form action = "" method = "post" enctype=multipart/form-data> 
  21.         <input type = "file" name = file> 
  22.         <input type = "submit" value = Upload> 
  23.     </form> 
  24.     '''  
  25.  
  26. @main.route('/uploaded_file/<filename>')  
  27. def uploaded_file(filename):  
  28.     return send_from_directory(UPLOAD_FOLDER,filename)  


我创建了一张t.jpg的图片,里面用文本框写了一句话,也就是下面预览里面看到的



到这里为止,基本的上传和预览功能就实现了,后面还要再和用户头像挂钩,还得再动动脑子。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值