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 - 爱码网

一. Python 现阶段三大主流Web框架 Django Tornado Flask 对比

1.Django 主要特点是大而全,集成了很多组件,例如: Models Admin Form 等等, 不管你用得到用不到,反正它全都有,属于全能型框架

2.Tornado 主要特点是原生异步非阻塞,在IO密集型应用和多任务处理上占据绝对性的优势,属于专注型框架

3.Flask 主要特点小而轻,原生组件几乎为0, 三方提供的组件请参考Django 非常全面,属于短小精悍型框架

Django 通常用于大型Web应用由于内置组件足够强大所以使用Django开发可以一气呵成

Tornado 通常用于API后端应用,游戏服务后台,其内部实现的异步非阻塞真是稳得一批

Flask 通常应用于小型应用和快速构建应用,其强大的三方库,足以支撑一个大型的Web应用

Django 优点是大而全,缺点也就暴露出来了,这么多的资源一次性全部加载,肯定会造成一部分的资源浪费

Tornado 优点是异步,缺点是干净,连个Session都不支持

Flask 优点是精悍简单

总结:

Flask:
    优点:小而精,短小精悍,第三方组件特别多
    缺点:组件更新速度取决于开源者,你不会
    
Tornado:
    优点:原生的WebSocket,异步任务,IO非阻塞
    缺点:组件没有,Session都没有
    
Django:
    优点:大而全,组件非常全面
    缺点:太大,加载太大,浪费资源

 二、Flask 的安装与简单使用

pip install Flask

最简单的Flask项目,Flask三行:

from flask import Flask
    apl = Flask(__name__)
    apl.run()

三、三种返回页面的方式

from flask import Flask, render_template, redirect

# 一个flask对象
app = Flask(__name__)

STUDENT_LIST = [ {'name': 'Old', 'age': 38, 'gender': '中'},
           {'name': 'Boy', 'age': 73, 'gender': '男'},
           {'name': 'EDU', 'age': 84, 'gender': '女'} ]
# render 注意, templates文件要和当前py文件同级,不然会找不到,报一个Jinja2的异常哦 @app.route('/index') def index(): html_msg = '<h1>my html</h1>' markup_tag = Markup(html_msg) # 相当于在html页面加上 safe ,这里写了,前端页面就不用写了 return render_template('index.html', stu=STUDENT_LIST, markup_tag=markup_tag, tag="") # HTTPResponse @app.route('/') def one_test(): return 'hello girl' # redirect @app.route('/hello') def hello(): return redirect('/index')


if __name__ == '__main__':
    # debug模式运行
    app.run(debug=True)

四、模版语言

1.模版函数

2、数据安全

3、 for if 等的用法和django里的一样

4、模版继承的用法也和django一样,就不写了

举个栗子:

在 app.py 中

#########  在Jinja2中执行Python函数(模板中执行函数) ############
@app.template_global()  # 定义全局模板函数
def a_b_sum(a, b):
    return a + b


@app.template_filter()  # 定义全局模板函数
def a_b_c_sum(a, b, c):
    return a + b + c


def index():
    html_msg = '<h1>my html</h1>'
    markup_tag = Markup(html_msg)  # 相当于在html页面加上 safe ,这里写了,前端页面就不用写了
    return render_template('index.html', stu=STUDENT_LIST, markup_tag=markup_tag, tag="")

在index.html页面里

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <!-- 在Jinja2中执行Python函数(模板中执行函数) -->
     {{ a_b_sum(99,1) }}
    <br>
    {{ 1 | a_b_c_sum(197,2) }}

    <!-- 插入 markup 处理后的html标签 -->
    {{ markup_tag }}     

  <table>
      <thead>
      <tr>
          {% for foo in stu[0] %}
            <td>{{ foo }}</td>
          {% endfor %}
      </tr>
      </thead>
      <tbody>
        {% for st in stu %}
            <tr>
                {% for t in st %}
                    <td>{{ st[t] }}</td>
                {% endfor %}

            </tr>
        {% endfor %}
      </tbody>
  </table>

</body>
</html>

五、一个简单的登录认证

1、request 的使用

2、session的应用

  • Flask中的Session非常的奇怪,他会将你的SessionID存放在客户端的Cookie中,使用起来也非常的奇怪
  • secret_key 实际上是用来加密字符串的,如果在实例化的app中没有 secret_key 那么开启session一定会抛异常的
  • cookies 中 session 存储的是通过 secret_key 加密后的 key , 通过这个 key 从flask程序的内存中找到用户对应的session信息

3、装饰器的使用及遇到的问题

4、类似Django中间件,.@app.before_request 和 @app.after_request    errorheadler

先看代码吧~

在app.py中:

from flask import Markup  # 导入 flask 中的 Markup 模块 
from flask import Flask, render_template, redirect 
from flask import request 
from flask import session

# 一个flask对象 
app = Flask(__name__) 
# cookies 中 session 存储的是通过 secret_key 加密后的 key , 通过这个 key 从flask程序的内存中找到用户对应的session信息 
app.secret_key = "LYJ" 

import functools

# 一个认证装饰器
def my_auth(func):
    @functools.wraps(func)
    def war(*args, **kwargs):
        if session.get('user'):
            return func()
        else:
            return redirect('/login')

    return war


@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        print(request.form)  # ImmutableMultiDict([('username', 'qwe'), ('pwd', '123')])
        username = request.form['username']  # 以字典方式取值
        pwd = request.form.get('pwd')
        print(username, pwd)

        # session的应用
        session['user'] = username
        return redirect('/index')
    if request.method == 'GET':
        return render_template('login.html')


# 认证,自定义装饰器的使用
@app.route('/index2', endpoint='index2')
@my_auth
def index2():
    return redirect('/index')  #用的是示例模版的那个index


@app.route('/index3', endpoint='index3')
@my_auth
def index3():
    return redirect('/index')


#  AssertionError: View function mapping is overwriting an existing endpoint function: war
# 因为在经过装饰器后 func 的 __name__都变成了装饰器的名字,所以 route 在处理时,会取到多个一样的方法名
# 有两种解决办法 1、 在装饰器中加上 装饰器修复  @functools.wraps(func)  2、 用endpoint给传入route的函数命名: @app.route('/index3',endpoint='index3')


if __name__ == '__main__':
    # debug模式运行
    app.run(debug=True)

 

如果直接加装饰器的话,会报错

AssertionError: View function mapping is overwriting an existing endpoint function: war

 原因:在经过装饰器后 func 的 __name__都变成了装饰器的名字,所以 route 在处理时,会取到多个一样的方法名
有两种解决办法 

1、 在装饰器中加上 装饰器修复  @functools.wraps(func) 

2、 用endpoint给传入route的函数命名: @app.route('/index3',endpoint='index3')

注意:

  装饰器应该放在最靠近函数的地方,因为装饰器的执行顺序是从最靠近的那个开始的,不这样写的话会不行该函数,详见:多个装饰器的执行顺序

 另一种处理登录认证的方式,类似于Django的中间件 

1.@app.before_request 在请求(request)之前做出响应

from flask import Flask
from flask import request
from flask import redirect
from flask import session

app = Flask(__name__)  # type:Flask
app.secret_key = "DragonFire"


@app.before_request
def is_login():
    if request.path == "/login":
        return None

    if not session.get("user"):
        return redirect("/login")


@app.route("/login")
def login():
    return "Login"


@app.route("/index")
def index():
    return "Index"


@app.route("/home")
def home():
    return "Login"


app.run("0.0.0.0", 5000)

相关文章: