array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 Flask入门文件上传flask-uploads(八) - 爱码网

1 视图传递多个参数

**(1) 普通传参 **: 关键字参数传递

return render_template('模板名称.html',arg1=val1,arg2=val2...)

(2) 字典传参 : 以字典的形式传递

dict = {
    key1:value1,
    key2:value2,
    ....
}
return render_template('模板名称.html',dict)

(3) 全局变量g传递

视图中:

@app.route('/test')
def test():
    g.name = '张三'
    g.sex = '男'
    return render_template('test.html')

模板中

 <h2>{{ g.name }}</h2>
 <h2>{{ g.sex }}</h2>

(4) 传递全部的本地变量给template,使用locals()**,直接获取变量值

@app.route('/test')
def test():
    name = '张三'
    sex = '男'
    return render_template('test.html',**locals())

test.html中

<h2>{{ name }}</h2>
<h2>{{ sex }}</h2>

2 错误页面定制

#制定捕获404和500的错误页面
@app.errorhandler(404)
def page_not_found(e):
    return render_template('error.html',error=e,code=404)

@app.errorhandler(500)
def page_not_found(e):  #接受参数e,并传给错误error
    return render_template('error.html',error=e,code=500)

指定错误页面:只需要一个错误模板页面即可

{% extends 'common/boot_base.html' %}
{% block title %}
{{ code }}  #标题显示500
{% endblock %}
{% block page_content %}
    <div class="alert alert-danger" role="alert">{{ error }}  #显示错误页面信息
</div>
{% endblock %}

3 文件上传

(1) 静态资源的加载

{{ url_for('static',filename='img/mei.jpg') }} 
{{ url_for('static',filename='css/style.css') }} 
{{ url_for('static',filename='js/mei.js') }} 

#注:static是内置的视图函数,我们通过其找到路由

(2) 原生文件上传

模板文件

{% if newName %}  #newName非空 图片名传入
	<img src='{{ url_for("static",filename=newName) }}' alt=''>
{% endif %}
#视图函数upLoad  
<form action="{{ url_for('upLoad') }}" enctype='multipart/form-data' method='post'>
	<input type='file' name='file'>
    <p><input type='submit' value='submit'></p>
</form>

主文件manage.py

from flask import Flask,render_template,request
from flask_script import Manager
from flask_bootstrap import Bootstrap
import os
from PIL import Image  #python图片处理库

app = Flask(__name__)
#允许上传的后缀名,放在配置文件
app.config['ALLOWED_EXTENSIONS'] = ['.jpg','.jpeg','.png','.gif']
#上传文件的大小
app.config['MAX_CONTENT_LENGTH'] = 1024*1024*60
#配置文件上传的路径
app.config['UPLOAD_FOLDER'] = os.getcwd() + '/static'

#绑定bootstrap
bootstrap = Bootstrap(app)
manager = Manager(app)

@app.route('/')
def index():
    return render_template('index.html')

#生成随机图片名称的函数
def new_name(shuffix,length=32):
    import string,random
    myStr = string.ascii_letters + '0123456789'
    newName = ''.join(random.choice(myStr) for i in range(length))
    return newName+shuffix

#定义判断后缀是否可用函数,返回true/false
def allowed_file(shuffix):
    return shuffix in app.config['ALLOWED_EXTENSIONS']

@app.route('/upload',methods=['GET','POST'])
def upload():
    img_name = None
    if request.method == 'POST':
        file = request.files.get('file')
        #获取上传文件的名称
        filename = file.filename
        #分割路径,返回路径名和文件扩展名的元组
        shuffix = os.path.splitext(filename)[-1]
        if allowed_file(shuffix):
            #为真则生成随机名称
            newName = new_name(shuffix)
            img_name = newName
            #拼凑完整的路径
            newPath = os.path.join(app.config['UPLOAD_FOLDER'],newName)
            file.save(newPath)
            
            #处理图片的缩放
            img = Image.open(newPath)
            #重新设置大小与尺寸
            img.thumbnail((200,200))
            img.save(newName)
     #跳转上传页面并返回newName
     return render_template('upload.html',newName=img_name)

4 flask-uploads扩展库

安装

pip3 install flask-uploads

类UploadSet : 文件上传配置集合,包含三个参数:

name:文件上传配置集合的名称,默认files

extensions:上传文件类型,默认DEFAULTS = TEXT + DOCUMENTS + IMAGES + DATA

default_dest:上传文件的默认存储路径,我们可以通过app.config[‘UPLOADS_DEFAULT_DEST’]来指定

方法 : configure_uploads

应用配置好之后,调用此方法,扫描上传配置选项并保存到我们的应用中,注册上传模块。

下面我们来看下 (flask-uploads库 + flask-wtf 库) 的写法

模板文件

{% extends 'common/base.html' %}  #继承
{% block title %}
    首页
{% endblock %}
{% import 'bootstrap/wtf.html' as wtf %}  #导入
{% block page_content %}
    <img src="{{ url_for('static',filename=newName) }}" alt="">
    {{ wtf.quick_form(form) }}   #快速渲染
{% endblock %}

主启动文件

from flask import Flask,render_template,request
from flask_script import Manager
from flask_bootstrap import Bootstrap
import os
from flask_uploads import UploadSet,IMAGES,configure_uploads,patch_request_class
#导入库中验证的字段类
from flask_wtf import FlaskForm
from wtforms import FileField,SubmitField
from flask_wtf.file import FileAllowed,FileRequired

app = Flask(__name__)
#允许上传的后缀
app.config['SECRET_KEY'] = 'image'
app.config['MAX_CONTENT_LENGTH'] = 1024*1024*64 #64兆
#配置文件上传的路径
app.config['UPLOADED_PHOTOS_DEST'] = os.getcwd()+'/static/upload'

#实例化一个file对象  photos与PHOTOS要对应
file = UploadSet('photos',IMAGES)
#将 app 的 config 配置注册到 UploadSet 实例 file
configure_uploads(app,file)
#限制上传文件的大小   size=None不采用默认size=64*1024*1024
patch_request_class(app,size=None)

bootstrap = Bootstrap(app)
manager = Manager(app)

class File(FlaskForm):
    file = FileField('文件上传',validators=[FileRequired(message='您还没有选择文件'),FileAllowed(file,message='只能上擦图片')])
    submit = SubmitField('上传')

#生成随机图片名称的函数
def new_name(shuffix,length=32):
    import string, random
    myStr = string.ascii_letters + '0123456789'
    newName = ''.join(random.choice(myStr) for i in range(length))
    return newName+shuffix

@app.route('/upload',methods=['GET','POST'])
def upload():
    form = File()
    img_url = None
	#验证数据
    if form.validate_on_submit():
        shuffix = os.path.splitext(form.file.data.filename)[-1]
        newName = new_name(shuffix=shuffix)
        file.save(form.file.data,name=newName)
        img_url = file.url(newName)
    return  render_template('boot_upload.html',newName=img_url,form=form)

if __name__ == '__main__':
    manager.run()

注意事项:

 将app的config配置注册到 UploadSet 实例file   configure_uploads(app,file)
 限制上传文件的大小    patch_request_class(app,size=None)
 file = UploadSet('photos',IMAGES)  实例化file对象继承了类中save()  url() 内置方法
 form = File()  File类继承自FlaskForm  可以利用flask-uploads库进行验证 , 采用类File取代原生的Form表单访问通过 : 
   实例化form对象.字段名.data    		访问字段对象
   实例化form对象.字段名.data.属性名    访问字段对象对应的属性

相关文章: