Flask上传文件

回顾知识点form表单中,一旦涉及到上传文件就要就必须要有enctype属性,而且必须等于multipart/form-data.而且提交方式为‘post’,method = 'post'

步骤首先给form表单添加enctype属性和method属性enctype = 'multipart/form-data'

method = 'post'

在项目的根目录中创建文件保存路径。

指定文件的保存路径# os.path.dirname(__file__)获取的是app.py文件的路径,也就是在项目根目录中,然后把它放在images文件夹中

UPLOAD_PATH = os.path.join(os.path.dirname(__file__),'images')

if..else两种情况当页面访问为get方式直接跳转,post方式进行操作

后台要获取上传的文件,用request.files.get('文件名')来获取

保存文件之前,使用werkzeug.utils.secure_filename来对上传上来的文件名进行一个过滤。保证不会有安全问题。

获取到上传上来的文件后,使用文件对象.save(路径)方法来保存文件。路径=完整路径=路径名+文件名

代码实现

html代码

上传文件

{# 但凡form中涉及到了上传文件,那么method = 'post' 和 enctype = 'multipart/form-data'#}

{# 当没有指定提交路劲时,默认向当前页面提交#}

头像:
心情:

Py代码

# 上传文件优化,文件名安全的意思

from werkzeug.utils import secure_filename

# os.path.dirname(__file__)获取的是app.py文件的路径,也就是在项目根目录中,然后把它放在images文件夹中

UPLOAD_PATH = os.path.join(os.path.dirname(__file__),'images')

# Flask上传文件的实现

@app.route('/upload/',methods=['POST','GET'])

def upload():

if request.method == 'GET':

return render_template('upload.html')

else:

desc = request.form.get('desc')

# 获取pichead文件对象

pichead = request.files.get('pichead')

print(desc)

# 保存到服务器

# save方法传完整的路径和文件名

# pichead.save(os.path.join(UPLOAD_PATH,pichead.filename))

# 上行可以进行优化,下行是对pichead文件名进行包装,保证文件名更安全。

filename = secure_filename(pichead.filename)

pichead.save(os.path.join(UPLOAD_PATH,filename))

return '文件上传成功

访问上传成功的文件

原理从服务器中读取,应该定义一个url与视图函数,来获取指定的文件。

在视图函数中,使用send_from_directory(文件目录,文件名)来获取。

实现

# 访问已经上传号的服务器上的文件,要借助flask中的send_from_directory函数

from flask import send_from_directory

# 访问服务器上的文件(已经上传成功的文件)

@app.route('/images/')

def get_image(filename):

return send_from_directory(UPLOAD_PATH,filename)

利用flask-wtf验证上传文件

原理借用wtforms和flask_wt内的函数,验证文件

关键之处对文件类型字段的验证,需要采用wtforms中的FileField这个类型

验证器需要从flask_wtf.file中导入,flask_wtf.file.FileRequired和flask_wtf.file.FileAllowed类型

FileRequired是用来验证文件上传不能为空。

FileAllowed用来验证上传的文件的后缀名

(重要)在视图函数中,需要使用from werkzeug.datastructures import CombinedMultiDict来吧from和files进行合并。

最后使用 if语句对表单验证对象.validate()进行验证

代码实现

formscheck文件

from wtforms import Form,FileField,StringField

from wtforms.validators import InputRequired

# flask_wtf

from flask_wtf.file import FileRequired,FileAllowed

class UploadForm(Form):

pichead = FileField(validators=[FileRequired(),FileAllowed(['jpg','png','gif'])])

desc = StringField(validators=[InputRequired()])

app文件

from flask import Flask,request,render_template

import os

from werkzeug.utils import secure_filename

from formscheck import UploadForm

from werkzeug.datastructures import CombinedMultiDict

app = Flask(__name__)

UPLOAD_PATH = os.path.join(os.path.dirname(__file__),'images')

#利用flask-wtf验证上传的文件

@app.route('/upload/',methods=['GET','POST'])

def upload():

if request.method == 'GET':

return render_template('upload.html')

else:

form = UploadForm(CombinedMultiDict([request.form,request.files]))

if form.validate():

# desc = request.form.get("desc")

# pichead = request.files.get("pichead")

desc = form.desc.data

pichead = form.pichead.data

filename = secure_filename(pichead.filename)

pichead.save(os.path.join(UPLOAD_PATH,filename))

print(desc)

return '文件上传成功'

else:

print(form.errors)

return "文件上传失败"

if __name__ == '__main__':

app.run(debug=True)

Flask_RESTful

Restful接口规范

介绍

什么是Restful?REST:Representational State Transfer ,指的是一组架构约束条件和原则,满足这些约束条件和原则的应用程序或者设计就是RESTful。

是一种软件架构风格、设计风格、而不是标准,只不过是提供了设计原则和交互条件。

是主要用于客户端和服务器交互类的软件,是用于前端和后台进行通信的一套规范,使用这个规范可以让开发变得更轻松。

适用场景PC端,移动端,app端,ios端都适用。

协议http或者https协议

数据格式要求必须使用json格式!!!

url连接规则url链接中不能有动词,只能由名词

对于一些名词,如果出现复数,那么应该在后面加news

举个栗子:应该使用‘/news/’,而不应该是‘/get_news/’

HTTP请求方式(部分)GET:从服务器上获取资源

POST:在服务器上新增或者修改一个资源(登录时除外)

PUT:在服务器上更新资源(客户端提供所有改变后的数据)

PATCH:在服务器上更新资源(客户端只提供需要改变的属性)

DELETE:在服务器上删除资源最常用的是GET和POST,后三项不怎么用,作为了解。

状态码客户端返回的状态码,可以通过状态码得知,程序的运行情况。

状态码原因描述描述200ok服务器成功响应400INVALID REQUEST用户发出的请求有错误,服务器没有进行新建或修改数据的操作401Unauthorized用户没有权限访问这个请求403Forbidden因为某些原因禁止访问这个请求404NOT FOUND用户请求的url不存在406NOT Acceptable用户请求不被服务器接收500Internal server error服务器内部错误,比如遇到bug

使用方式

Flask_RESTful介绍RESTful是基于类视图实现的,是专门用来写restful api的插件,可以快速集成restful_api接口功能,在纯api的后台中,节省开发时间。

不过在小的网站上,不需要使用RESTful,因为小网站返回的是页面(html),而RESTful返回的是Json数据格式

基本使用

步骤从flask_restful中导入API,创建api对象

定义类视图,继承于(Response类)在这其中,使用你想要的请求方式来定义相应的方法,比如你想要将这个类视图只能采用post请求,那么就定义一个post方法。

使用api..add_resource来添加url和视图函数

代码实现

from flask import Flask,url_for

from flask_restful import Api,Resource

app = Flask(__name__)

# 定义api

api = Api(app)

@app.route('/')

def hello_world():

return 'Hello World!'

# Flask_RESTful的基本使用

# 定义一个类视图

class LoginView(Resource):

def get(self):

return {"flag":"no"}

def post(self):

return {"flag":"yes"}

# 映射url

api.add_resource(LoginView,'/login/','/login2/',endpoint = 'login')

# 请求上下文

with app.test_request_context():

print(url_for('login')) # 如果不写endpoint,那么将会使用视图的名字的小写来作为endpoint

# 如果有endpoint,指定什么就必须使用endpoint值构建url

if __name__ == '__main__':

app.run(debug=True)

注意flask_restful和app.route的区别,在于看你想要返回什么。

想返回json数据结构→flask_restful,渲染模板→app.route

在api.add_response中可以指定多个url,以及endpoint

endpoint是用来给url_for反转url的时候指定的。如果不写endpoint,那么将会使用视图的名字的小写来作为endpoint。

功能参数验证方法

回顾参数验证的方法们JS表单验证

WTForms表单验证ps:RESTful和WTForms很类似,都是在服务器端做验证

参数解析(参数验证)

基本使用创建解析器对象(reqparse.RequestParser())

利用解析器对象,添加要验证的参数(add_argument)

利用解析器对象,进行验证,正确则返回验证合适的参数值,错误抛出异常(parser.parse_args())

代码实现

# restful中做参数验证的包。reqparse

from flask_restful import Api,Resource,reqparse

app = Flask(__name__)

api = Api(app)

# Flask_RESTful参数验证,基本用法

class RegisterView(Resource):

def post(self):

# 用户名

# 1、创建一个解释器对象

parse = reqparse.RequestParser()

# 2、利用解析器对象,添加需要的验证的参数

# parse .add_argument('要验证的', type=数据可是 , help='不符合规则信息' ,

# required = 是否必填(True) , trim = 信息前后空格去不去(True))

parse .add_argument('uname', type=str , help='用户名验证错误' , required = True , trim =True)

# 3、利用解析器对象,进行验证,若正确直接返回验证后合格的参数值,若错误,抛异常信息给客户端

args = parse.parse_args()

# 若验证成功后,需要插入数据库

print(args)

return {'tips':'注册成功'}

api.add_resource(RegisterView,'/register/')

add_argument

在add_argument函数中可以放置很多种参数,下面举一些常用的属性。default:默认值如果这个参数没有值,那么将使用这个参数指定的默认值。

required:是否必须。默认为False,如果设置为True,那么这个参数就必须提交上来。

type:这个参数的数据类型如果指定,那么将使用指定的数据类型来强制转换提交上来的值。

这里的数据类型,既包括python自带的数据类型,也可以使用flask_restful.inputs下的一些特定的数据类型来强制转换。

choices:固定选项。提交上来的值只有满足这个选项中的值才符合验证通过,否则验证不通过。

help:错误信息。如果验证失败后,将会使用这个参数指定的值作为错误信息。

trim:是否要去掉前后的空格

代码实现

# Flask_RESTful参数验证,更多用法

class RegisterView(Resource):

def post(self):

#用户名 密码 年龄 性别 出生日期 号码 个人主页

# 1.创建解析器对象

parser = reqparse.RequestParser()

#2.利用解析器对象添加 需要验证的参数

parser.add_argument('uname',type=str,help='用户名验证错误!',required=True,trim=True)

parser.add_argument('pwd', type=str, help='密码验证错误!',default="123456")

parser.add_argument('age',type=int,help='年龄验证错误!')

parser.add_argument('gender',type=str,choices=['男','女','双性'],help= '性别只能是男或者女')

# 注意要使用data和regex数据类型,需要到flask_restful.inputs中的。

parser.add_argument('birthday',type=inputs.date,help='生日字段验证错误!')

parser.add_argument('phone',type=inputs.regex(r'1[3578]\d{9}'),help = '请输入正确的电话号码')

parser.add_argument('phomepage',type=inputs.url,help='个人中心链接验证错误!')

#3.利用解析器对象进行验证,若正确,直接返回验证后合格的参数值,若错误,抛异常信息给客户端

args = parser.parse_args()

print(args)

return {"tips":"注册成功"}

api.add_resource(RegisterView,'/register/')

返回标准化参数

标准化思想对于一个类视图,你可以指定好一些字段作标准化用于返回。

以后使用ORM模型或者自定义模型的时候,他会自动的获取模型中的相应的字段,

生成json格式数据,然后再返回给客户端。

关键点(步骤)需要导入flask_restful.marshal_with装饰器

写一个字典变量,来指定需要返回的标准化字段,以及该字段的数据类型。

在get方法中,返回自定义对象的时候,flask_restful会自动的读取对象模型上的所有属性。

组装成一个符合标准化参数的json格式字符串返回给客户端。

代码实现

from flask import Flask

from flask_restful import Api,Resource,fields,marshal_with

app = Flask(__name__)

api = Api(app)

#flask_restful返回标准化参数

class News(object):

def __init__(self,title,content):

self.title =title

self.content =content

news = News('能力强的体现','能屈能伸')

class NewsView(Resource):

resource_fields ={

'title': fields.String,

'content':fields.String

}

# 这个装饰器是必须要用的哦~

@marshal_with(resource_fields)

def get(self):

# restful规范中,要求,定义好了返回的参数个数 和 内容

# return {'title':"世界太大",'content':"可钱包太小"}

#好处1:体现规范化,即使content这个参数没有值,也应该返回,返回一个null回去

# return {'title':"世界太大"}

#好处2:体现规范化,还可以返回一个对象模型回去

return news

api.add_resource(NewsView,'/news/')

if __name__ == '__main__':

app.run(debug=True)

返回标准化参数强化

重命名属性和默认值属性

需求1:

有的时候你对外给出的属性名和模型内部的属性名不相同时,可使用 attribute可以配置这种映射。比如想要返回模型对象user.username的值,但是在返回给外面的时候,想以uname返回去。

需求2:

在返回某些字段的时候,有时候可能没有值,但想给一个值用以提示,那么这时候可以在指定fields的时候使用default指定默认值。

代码实现

class User():

def __init__(self,username,age ):

self.username = username

self.age = age

self.signature = None

class UserView(Resource) :

resource_fields = {

# 1、重复名,把username重命名为uname,重点在于attribute = '原来的名字'

'uname':fields.String(attribute='username'),

'age':fields.Integer,

# 2、默认值 当signature没有任何值的时候,想要默认输出一个值,default = '想要输出的内容'

'signature':fields.String(default='没有什么')

}

# 这个是必须加的!!!!

@marshal_with(resource_fields)

def get(self):

user = User('MGorz',25)

return user

api.add_resource(UserView,'/user/')

复杂的参数结构复杂的参数结构,无非就是key对应的value又是一个json格式或者,key对应的是一个列表,而且列表中每项都是一个json。

这是就可以使用一些特殊的字段来实现了如果在一个字段中放置了一个列表,那么可以使用fields.List

如果在一个字段中下面又是一个json,那么可以使用fields.Nested

代码实现模拟环境:新闻系统后台 用户 新闻 新闻标签

# 复杂的参数结构

# 实体间关系有 1:1 1:n n:n(转为2个1:n)

# 新闻系统后台 用户 新闻 新闻标签

class User():

def __init__(self,id,uname,age):

self.id = id

self.uname = uname

self.age = age

# __str__ 和 __repr__

'''__str__打印出来只能看到地址值__repr__ 打印的时候,会把里面的全部显示出来'''

def __str__(self):

return "".format(id = self.id,uname = self.uname,age = self.age)

class News():

def __init__(self,id,title,content):

self.id = id

self.title = title

self.content = content

self.author = None

self.tags = []

def __repr__(self):

return ""\

.format(id=self.id,title = self.title,content = self.content,author=self.author,tags = self.tags)

class NewsTag():

def __init__(self,id,name):

self.id = id

self.name = name

def __repr__(self):

return "".format(id = self.id,name = self.name)

def createData():

user = User(110,'莫莫',30)

tag1 = NewsTag(200,"要闻")

tag2 = NewsTag(210,"娱乐")

news =News(300,'吴京征服了世界上海拔最高的派出所','4月23日中午11点,吴京发了一条微博,配文“世界上海拔最高的派出所”,并@了另外一名演员张译。微博中有两张图片,第一张是吴京和张译两人坐在地上的合照,背后几个大字“中国边防”。第二张则是两人与派出所民警们的合照。 ')

news.author = user #绑定新闻作者

news.tags.append(tag1) #绑定新闻标签1

news.tags.append(tag2) #绑定新闻标签2

print(news)

return news

class NewsView2(Resource):

resource_fields ={

'id':fields.Integer,

'title':fields.String,

'content':fields.String,

# 如果在一个字段下面又是一个字典,那么可以使用field.Nested({...})

'author':fields.Nested({

'id':fields.Integer,

'uname':fields.String,

'age':fields.Integer,

}),

# 如要在一个字段中放置一个列表,那么可以使用fields.List(fields.Nested({...}))

'tags':fields.List(fields.Nested({'id':fields.Integer,

'name':fields.String

}))

}

@marshal_with(resource_fields)

def get(self):

news = createData()

return news

api.add_resource(NewsView2,'/news2/')

结合蓝图使用关键点在于,创建API对象的时候,要创建蓝图对象,而不是app对象了。

代码实现(部分)

首先需要把所需要的代码复制粘贴到蓝图文件中。

blueprints/news.py:

from flask import Blueprint

# 定义蓝图,名字,__name__,前缀。。。。

news_bp = Blueprint('news_bp', __name__, url_prefix='/news')

# 此写法适用于在蓝图文件中使用,在蓝图文件中使用flask_restful写接口

api = Api(news_bp)

app.py:

# 导入蓝图文件

from blueprints.news import news_bp

# 注册蓝图

app.register_blueprint(news_bp)

渲染模板渲染模板需要借助api.representation装饰器,把代码按照规则进行解析

代码实现

# 2、渲染模板

class ListView(Resource):

def get(self):

return render_template('index.html')

api.add_resource(ListView,'/list/')

# 不引入装饰器api.representation执行操作之前,会默认把页面的html文件当做普通的字符串展现。

# 渲染模板啦~(一般是最前边),只支持html和json,常见的为text/html和text/javascript和application/json

@api.representation('text/html')

# 渲染模板,要解析成html文件,则需要传data(全文内容),code(状态码),header(头部信息),并且返回值必须是一个response对象

def out_html(data,code,headers):

if isinstance(data,str):

# 在representation装饰的函数中,必须返回一个Response对象

resp = make_response(data)

# 借助于make_response()函数可以创建一个Response对象。

# resp =Response(data)

return resp

else:

# mimetype='application/json'告诉客户端浏览器,对于相应回去的内容按照json的格式解析

return Response(json.dumps(data),mimetype='application/json')

拓展知识make_response函数可以把任何一个数据转化为Response对象

python flask上传文件_Python之利用Flask上传文件、Flask_RESTful相关推荐

  1. exew文件加密:利用破解版exe文件加密器对exe文件进行加密保护(图文教程)

    exew文件加密:利用破解版exe文件加密器对exe文件进行加密保护(图文教程) 目录 加密过程步骤 解密过程步骤 加密过程步骤 解密过程步骤

  2. python post 上传文件_Python通过POST方式上传文件及提交参数到远程服务器

    前言 在树莓派开发过程中,因为没有公网IP,为了方便访问获取信息,有时候我们需要将树莓派获取到的一些数据或文件上传到云端服务器.这是一个比较简便的方法. Python代码 需要用到requests库, ...

  3. python程序多次运行_Python内怎么使同一个.py文件多次运行?

    原博文 2020-08-03 15:57 − 当在多个客户端同时连接一个服务端时需要同时运行多个客户端所在的.py文件,但默认上我们运行了一次后如果再想运行这个.py文件,则被要求停下当前运行的.py ...

  4. python打包和添加数据文件_Python打包时添加非代码文件的坑

    Title: Python打包时添加非代码文件的坑 Tags: python, 小结 对于 Python 的打包, 通常有两种, 一种是对源文件打包, 一种是安装包, 既在上传 pypi 的时候一般会 ...

  5. python生成epub文件_python在内存中生成Zip文件!

    import zipfile import StringIO class MemoryZipFile(object): def __init__(self): #创建内存文件 self._memory ...

  6. python解压zip文件_python怎样压缩和解压缩ZIP文件(转)

    有时我们需要在 Python 中使用 zip 文件,而在1.6版中,Python 就已经提供了 zipfile 模块可以进行这样的操作.不过 Python 中的 zipfile 模块不能处理多卷的情况 ...

  7. python中bttext什么意思_Python实现解析Bit Torrent种子文件内容的方法

    有人会 python语言 对BT种子解析 吗bt的客户端,本来就有纯python编写的. 你找一个下载就可以了. 我印象中bittorrent就是python编写的. python开发很方便,也很快. ...

  8. python读取zip包内文件_Python模块学习:zipfile zip文件操作

    最近在写一个网络客户端下载程序,用于下载服务器上的数据.有些数据(如文本,office文档)如果直接传输的话,将会增加通信的数据量,使下载时间变长.服务器在传输这些数据之前先对其进行压缩,客户端接收到 ...

  9. python调用pyc文件_Python之code对象与pyc文件(二)

    创建pyc文件的具体过程 前面我们提到,Python在通过import或from xxx import xxx时会对module进行动态加载,如果没有找到相应的pyc或dll文件,就会在py文件的基础 ...

最新文章

  1. php json 数组 区别,PHP实战:JSON两种结构之对象和数组的理解
  2. 关于Infobright的一个小TIPS
  3. C#调用ATL COM
  4. 网络请求之优化参数添加工具类自定义Map类
  5. php学语法,PHP入门学习——PHP语法
  6. 一起助力!为wuhan2020:武汉新型冠状病毒防疫开源信息收集平台尽一份微薄之力!...
  7. 自动化测试selenium基础面试技巧?
  8. bzoj1651: [Usaco2006 Feb]Stall Reservations 专用牛棚
  9. 如何查看APP ID
  10. 调用百度API 实现车型识别
  11. 基于mpvue创建微信小程序项目
  12. fprintf用法解析
  13. 。三十功名尘与土,八千里路云和月。莫等闲,白了少年头,空悲切
  14. 使用VM安装Centos7虚拟机
  15. 查看电脑使用了多长时间
  16. EasyExcel v2.1.6单元格样式设置
  17. LearnOpenGL学习笔记—高级光照 09:SSAO
  18. node : 无法将“node”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正 确,然后再试一次 的解决方案
  19. 数据分析师+前途无忧爬虫分析
  20. FastRNABindR:快速准确预测蛋白质-RNA界面残基

热门文章

  1. 简单五子棋,加入存储,读取功能
  2. 基于Cesium的火箭发射演示
  3. 一览各类无人飞机设计方法
  4. 预言机理解:A Scalable Architecture for On-Demand, Untrusted Delivery of Entropy
  5. Windows 8 自带定时关机的4种实现方法
  6. 小米为什么要“抛弃”红米?
  7. 判断全角与半角及两者之间的转换
  8. 罗切斯特大学排名计算机排名,罗切斯特大学计算机工程硕士排名第35(2020年TFE Times排名)...
  9. 避免刷新页面时重复提交表单数据
  10. python爬虫(9)获取动态搞笑图片