Flask框架

1、flask框架初识

Flask是一个Python编写的Web 微框架,让我们可以使用Python语言快速实现一个网站或Web服务,
在介绍Flask之前首先来聊下它和Django的联系以及区别,django个大而全的web框架,它内置许多
模块,flask是一个小而精的轻量级框架,Django功能大而全,Flask只包含基本的配置, Django的
一站式解决的思路,能让开发者不用在开发之前就在选择应用的基础设施上花费大量时间。Django
有模板,表单,路由,基本的数据库管理等等内建功能。与之相反,Flask只是一个内核,默认依赖
于2个外部库: Jinja2 模板引擎和 WSGI工具集--Werkzeug , flask的使用特点是基本所有的工具
使用都依赖于导入的形式去扩展,flask只保留了web开发的核心功能。
WSGI(web服务器网关接口)是python中用来规定web服务器如何与python Web服务器如何与Python 
Web程序进行沟通的标准,本质上就是一个socket服务端。而 Werkzeug模块 就是WSGI一个具体的
实现
关键词:一个Python编写微web框架 一个核心两个库( Jinja2 模板引擎 和 WSGI工具集)

2、为什么要有flask

flask性能上基本满足一般web开发的需求, 并且灵活性以及可扩展性上要优于其他web框架, 对各种数据库的契合度都非常高

关键词

  • 性能基本满足要求
  • 灵活性可扩展性强
  • 对各种数据库的契合性度都比较高
  • 在真实生产环境下,小项目开发快,大项目设计灵活

3、第一个flask程序

from flask import Flask

"""
导入我们安装好的flask包,通过flask包导入Flask类,Flask类即为Flask的核心,实例化这个Flask类的到一个实例化对象app。

__name__这个特殊的参数:Python会根据所处的模块来赋予__name__变量相应的值,对于我们的程序来说(app.py),这个值为app。
"""
app = Flask(__name__)

"""
@app.route('/')就是用来匹配url的,在我们的flask里面是以装饰器来实现的,装饰器引用的也是我们上面实例化核心类出来的对象。
"""
@app.route('/')
def index():
    return 'hello flask!'

"""
app.run()实现了flask程序在开发环境下运行起来,并且默认ip和端口是127.0.0.1:5000
具体内容可以在源码run方法可以看到
"""
if __name__ == '__main__':
    app.run()

4、 Werkzeug简介

Werkzeug是一个WSGI工具包,他可以作为一个Web框架的底层库。这里稍微说一下, werkzeug 不是一个web服务器,也不是一个web框架,而是一个工具包,官方的介绍说是一个 WSGI 工具包,它可以作为一个 Web 框架的底层库,因为它封装好了很多 Web 框架的东西,例如 Request,Response 等等 。

from werkzeug.wrappers import Request, Response

@Request.application
def hello(request):
    return Response('Hello World!')

if __name__ == '__main__':
    from werkzeug.serving import run_simple
    run_simple('localhost', 4000, hello)

flask正是依赖于这个werkzeug模块,由wekzeug模块实现了socket服务端的功能,hello必然是加括号运行了,才会执行hello里面的代码,而在我们的flask中app.run()会调用run_simple(host, port, self, **options)把上面代码例子的hello替换成了self也就是app。app()会触发Flask类的__call__方法。

所以所flask程序的入口就在__call__方法中,而__call__方法返回self.wsgi_app(environ, start_response),所以整个程序的执行过程都在 self.wsgi_app(environ, start_response)中.

1 app.run() 调用 werkzeug.serving的run_simple(host, port, self, **options)

2 self()等价于app(), app()调用Flask类的__call__方法

3 Flask类的__call__方法返回了 self.wsgi_app(environ, start_response)

4 flask程序的执行过程都在 self.wsgi_app(environ, start_response)中

关键词

  • Werkzeug是一个WSGI工具包,本质上是一个socket服务端。
  • flask基于Werkzeug,flask只保留了web开发的核心功能。
  • flask的执行过程都在def wsgi_app(self, environ, start_response):

5、登录,显示用户信息案例

app.py

from flask import Flask, request, render_template, redirect, session, jsonify

# flask中的请求对象是全局的request
# render_template 就是django的render

app = Flask(__name__)
# 使用session,一定要设置秘钥,等同于django配置文件中的密码
app.secret_key = 'adfae^^4384045532@@#$#'
app.debug = True  # 启用调试模式,修改了代码不用重启,自动重启
USERS = {
    1: {'name': '张三', 'age': 18, 'gender': '男', 'text': "道路千万条"},
    2: {'name': '李四', 'age': 28, 'gender': '男', 'text': "安全第一条"},
    3: {'name': '王五', 'age': 18, 'gender': '女', 'text': "行车不规范"},
}


@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('login.html')
    else:
        # request.form 等同于request.POST
        name = request.form.get('user')
        password = request.form.get('pwd')
        if name == 'lqz' and password == '123':
            # 登录成功,重定向到首页
            # 把登录信息放到session中
            session['name'] = name
            return redirect('/')
        else:
            return jsonify({'code': 101, 'msg': '用户名或密码错误'})


@app.route('/', methods=['GET'])
def index():
    if session.get('name'):
        return render_template('index.html', user_dict=USERS)
    else:
        # 没有登录,重定向到登陆页面
        return redirect('/login')


# @app.route('/detail/<int:pk>', methods=['GET'])
# def detail(pk):
@app.route('/detail', methods=['GET'],endpoint='detail')
def detail():
    print(request.query_string)  # b'pk=1&name=lqz&age=19'
    pk = int(request.args.get('pk'))
    print(pk)
    user_detail = USERS.get(pk)
    return render_template('detail.html', info=user_detail)


if __name__ == '__main__':
    app.run(port=8080)

### 总结
'''
0 当次请求的对象,request对象是全局的,直接导入使用即可
1 前端post提交的数据,从flask中的:request.form中取
2 转换器的使用/detail/<int:pk>
3 模板语法兼容django的dtl,可以直接使用函数加括号,并且可以传参数
4 session也是全局对象,用户登录信息,放到session中
5 新手四件套
    '字符串'---》HttpResonse('字符串')
    redirect('/')---》redirect('/')
    render_template()--->render()
    jsonify          ---->JsonResponse()
5 前端get请求提交的数据,从request.args
6 request.query_string是get请求 ? 后面的内容,bytes格式
7 @app.route('/detail', methods=['GET'],endpoint='detail')  endpoint等同于django路由中的name别名
'''

detail.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>
 <h1>详细信息 {{info.name}}</h1>
    <div>
        {{info.text}}
    </div>
</body>
</html>

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>用户登录</h1>
<form method="post">
    <input type="text" name="user">
    <input type="text" name="pwd">
    <input type="submit" value="登录">{{error}}
</form>
</body>
</html>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>
    <h1>用户列表</h1>
    <table>
        {% for k,v in user_dict.items() %}
        <tr>
            <td>{{k}}</td>
            <td>{{v.name}}</td>
            <td>{{v['name']}}</td>
            <td>{{v.get('name')}}</td>
            <td><a href="/detail/{{k}}">查看详细1</a></td>
            <td><a href="/detail?pk={{k}}&name=lqz&age=19">查看详细2</a></td>
        </tr>
        {% endfor %}
    </table>
</body>
</html>

6、Flask配置文件

# flask.config.Config


方式一:直接写app.config['DEBUG']    一般不用
方式二:放到py文件中                  一般不用
方式三:通过环境变量                  一般不用
app.config.from_envvar("环境变量名称")
app.config.from_json("json文件名称")
JSON文件名称,必须是json格式,因为内部会执行json.loads
app.config.from_mapping({'DEBUG': True})

方式四: 通过类的方式                 用的多
app.config.from_object('settings.DevelopmentConfig')
物联沃分享整理
物联沃-IOTWORD物联网 » Flask框架新手入门配置

发表评论