初识 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的应用

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

先看代码吧~

在app.py中:

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')

注意:

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

猜你喜欢

转载自www.cnblogs.com/95lyj/p/9508443.html
今日推荐