美文网首页
(一) flask入门介绍

(一) flask入门介绍

作者: fanhang64 | 来源:发表于2018-03-20 20:49 被阅读180次

    本系列的内容来自读书笔记:《Flask Web 开发 :基于 Python 的 Web 应用开发实战》

    一. flask入门

    WEB工作原理

    • C/S和B/S架构

    • B/S架构的工作原理

      客户端(浏览器)《=》WEB服务器(Apache,nginx)《=》WSGI《=》Python(flask)

    二. Flask框架

    (1) 简介

    flask是一个非常小的python web框架, 被称为微型框架, 只提供了一个强健的核心, 其他的功能都是通过扩展来实现的, 所以会使用很多的扩展模块

    (2) 组成

    1. 调试, 路由, wsgi
    2. 模板引擎
    3. 安装
    pip install flask
    
    4. 路由的配置
    @app.route('/')  # app可以随意起名字
    def index():
        # 视图函数
        pass
    
    5. 完整代码
    from flask import Flask  # 导入flask
    # 创建flask实例
    app = Flask(__name__)
    # 配置路由
    @app.route('/')
    def index():
        return '我是首页'
    if __name__ == '__main__':
        app.run()
    

    然后浏览器输入http://127.0.0.1:5000

    6. 启动参数run(debug, port, host, threaded)
    参数 说明
    debug 是否开启调试模式(True/False), 默认为False, 如果开启会自动加载代码
    port 指定端口号
    host 指定主机名 设置为0.0.0.0
    threaded 是否开启多线程, 默认False

    实例:

     app.run(debug=True,port=5050,threaded=True,host='0.0.0.0')
    
    7.请求和响应
    变量和对象 说明
    current_app 当前运行应用的实例
    g 处理请求的临时变量, 每次请求都会重置
    request 请求对象, 保存客户端的所有HTTP请求的信息
    session 会话控制 用于存储会话信息

    app对象:

    全局应用对象

    作用: 公共的全局配置, 可以加在这个对象上

    实例:

    # 给全局对象添加一个属性
    app.good = 'goods'
    

    current_app

    在任何的视图中, 可以使用current_app访问到全局的app对象

    作用: 因为公共的配置都写在了app对象上, 所以可以在所有的视图函数中, 通过current_app访问全局对象app

    from flask import current_app
    @app.route('/globalapp/')
    def globalapp():
        return '%s 获取全局good属性值, 通过current_app' % current_app.good
    

    request

    作用: 获取请求报文中的数据

    概述:

    • 浏览器发送到服务器中的所有报文被flask接收后, 创建request对象, request对象被用在视图函数中, 获取请求的数据
    • request对象由flask创建好以后, 引入就可以使用
    • 导入from flask import request

    属性:

    1. url : 完整请求url

    2. base_url: 去掉GET参数的url

    3. host_url: 只有主机ip和端口号

    4. path: 路由地址

    5. method: 请求方式

    6. remote_addr: 客户端的ip地址

    7. args: 获取GET请求的参数

      print(request.args['name'])  # 获取参数
      print(request.args.get(['age']))  # 获取参数,获取不到返回None
      
    8. form: 存储表单的数据

    9. files: 用于文件上传

    10. headers: 获取所有的请求头信息

    11. cookies: 获取cookie

    获取GET参数:

    # http://127.0.0.1:5000/?a=xxx&a=18
    print(request.args.get('a',))  # xxx 存在相同的返回第一个
    print(request.args.getlist('a',))  # 获取同名的多个参数, 返回列表
    

    三. 路由设置

    (1) 无参路由

    实例:

    @app.route('/test/')
    def test():
        return '测试无参路由'
    
    @app.route('/tt/')
    @app.route('/tt1/')
    @app.route('/tt2/')  # 可以同时添加多个路由
    def t():
        return '测试无参路由'
    

    注意: 路由的地址, 可以和视图函数的名称不一致

    (2) 有参路由

    实例:

    @app.route('/welcome/<name>')  # 一个参数的路由
    def welcome(name):
        return '欢迎 %s' % name
    # 浏览器输入http://127.0.0.1/welcome/张三
    
    # 多个参数的路由
    @app.route('/test/<a>/<b>')
    def t(a, b):
        print(a, b)
        return '多个参数'
    

    (3) 路由参数的限定

    实例:

    @app.route('/welcome2/<int:arg>')  # 只能匹配到整形  http://127.0.0.1/welcome/10
    @app.route('/welcome2/<float:arg>') # 只能匹配到浮点型  http://127.0.0.1/welcome/10.1
    @app.route('/welcome2/<string:arg>')  # 默认, 接受任何不带斜线的字符串
    @app.route('/welcome2/<path:arg>')  # 和string相似,但也接受斜线
    

    注意:

    1. 路由末尾的/建议都加上, 因为在路由需要/时浏览器会自动帮你加上, 也就是说输入的时候/可加可不加
    2. 若需要指定参数 将参数名称写在<>中, 视图(函数)的参数和路由的参数<u>名称</u>保持一致
    3. 若要限定参数的类型在<int/float/string/path:参数名称>
    4. 不指定类型默认为string类型, 如果使用path的话/不在是路由的分隔符, 而是代表路径

    四. 路由的响应(response)

    (1) 响应状态码404(但是请求成功)

    实例:

    @app.route('/res/')
    def res():
        return 'Page not Found ', 404  # 改变返回的状态码值,其实是请求成功的
    

    (2) 通过make_response来构造响应对象

    导入: from flask import make_response

    实例:

    @app.route('/res/')
    def res():
        respon = make_response('Page not found')  # 200 单纯的响应结果
        respon = make_response('Page not found', 404)  # 响应结果 改变http状态码
        return respon
    

    五. 重定向(redirect)

    作用: 可以在视图直接去跳转

    导入: from flask import redirect,url_for

    实例:

    @app.route('/r_redirect/')
    def r_redirect():
        return redirect('/test/', )  # 重定向, 参数为路由名称
        return url_for('t')  # 通过视图函数 反向构造出路由
        print(url_for('t',  a=1, b=2)) # /test/1/2 ,其中参数名a和b与视图函数对应
        return url_for('t', a=1, b=2)  # 通过视图函数 反向构造出路由和参数(关键字为参数名)
        return redirect(url_for('welcome2',arg=101))  # 重定向
    

    六.abort(终止)

    • 如果在视图处理中, 如果出现了异常错误, 可以使用abort函数立即终止视图函数的执行
    • 如果abort函数被触发, 后面的代码和程序就不在执行, 类似python的raise
    • 通过abort函数可以向前端(浏览器端)返回一个HTTP标准中的状态码, 表示出现错误的信息, 如果向浏览器返回一个不存在的Http状态码是没有任何意义的

    示例:

    @app.route('/')
    def index():
        abort(404)  # 抛出404的异常
        print("aa")  # 下面不在执行
        return '我是首页'
    

    错误页面的定制:

    @app.errorhandler(404)  # 括号中添加捕获状态码的值, 捕获404错误
    def page_not_found(e):  # 必须传一个参数
        print(e)
        return e  # e代表当前状态码对应的信息 正常会调用模板去显示对应状态码的页面
    

    七. 会话控制(cookie和session)

    (1) cookie

    参数:

    Response.set_cookie(
        key,
        value='',
        max_age=None,  # 以秒为单位的cookie寿命
        expires=None,  # 失效时间 datetime对象或者为Unix时间戳
        path='/'  # cookie的有效路径
    )
    

    设置cookie实例:

    @app.route('/set_cookie/')
    def setCookie():  
        response = make_response('设置cookie')
        # Response.set_cookie('name', 'zs')  # 设置cookie
        exp = time.time()+20  # 时间戳
        response.set_cookie('name', 'zs', expires=exp)  # 设置cookie过期时间
        response.set_cookie('name', 'zs', max_age=3600)  # 设置cookie一小时的过期时间
        return Response
    

    获取cookie的实例:

    @app.route('/get_cookie/')
    def getCookie():
        # 如果没有响应给浏览器会报错, 所有要有默认值
        return request.cookies.get('name', '默认值')  # 获取cookie的实例
        return request.cookies.get('nameaa')  #  如果获取不到会报错
        return request.cookies.get('nameaa') or 'default'  # 获取cookie的实例
    

    删除cookie的实例:

    @app.route('/del_cookie/')
    def delCookie():
        response = make_response('删除cookie')
        response.delete_cookie('name')
        return Response
    

    (2) session

    session基于cookie, session会将唯一标识符session-id存储于cookie中, 每次请求cookie会带着唯一的id去访问, 服务器端会根据唯一的id来区分每一个用户

    1. 设置session

    Flask对象会将会话储存在客户端的cookie中, 因此需要为应用实例的属性secret_key配置加密种子session, 才可以使用

    **导入session **

    from flask import session
    

    设置密钥(加密字符串)

    app.secret_key = '123456'  # 设置secret_key
    app.config['SECRET_KEY'] = '123456'  # 法二, 大写, 推荐使用
    

    设置session:

    @app.route('/set_session/')
    def setSesstion():
        session['age'] = 18    # 默认存活时间为浏览器会话结束时
        return '设置session'
    

    设置session带过期时间

    导入模块:from datetime import timedelta

    timedeltadatetime的一个对象, 该对象表示俩个时间的差值

    构造函数:

    datetime.timedelta(days=0,minutes=0,seconds=0,weeks=0,hours=0)
    

    实例:

    @app.route('/set_session/')
    def setSesstion():
        from datetime import timedelta
        session.permanent=True # 设置session开启持久化
        app.permanent_session_lifetime = timedelta(minutes=5)  # 设置存活时间为5分钟
        session['age'] = 18
        return '设置session'
    
    2. 获取session
    @app.route('/get_session/')
    def get_Session():
        return str(session.get('age', 'default'))  # 返回int不能响应,所以强转成str
    
    3. 删除session
    @app.route("/del_session/")
    def del_session():
        session.pop('age','default')  # 删除key为age的session
        session.clear()  # 删除当前session的所有数据(一个session可能包含name,age等)
        return '删除session'
    

    八. flask-script

    概念: 就是一个flask终端运行的解析器 因为项目测试完不需要更改任何的代码, 否则有可能会带风险, 所以要借助这个库通过更改命令完成不同的启动

    (2) 安装:pip install flask-script
    (3) 使用
    from flask-script import Manager
    app = Flask(__name__)
    manage = Manager(app)  # 实例化Manager
    if __name__ == '__main__':
        # app.run(debug=True)
        manage.run()    # 新添加的
    
    (4) 启动参数
    -?,--help  # 请求帮助
    -h,--HOST  # 设置主机名
    -p,--PORT  # 设置端口号
    --threaded  # 启用多线程
    -d  # 开启调试模式
    -r  # 开启自动加载
    

    实例:

    python 文件名.py runserver -h 0.0.0.0 -p 5000 -d -r
    python 文件名.py runserver -h 0.0.0.0 -p 5000 -d -r  --threaded
    

    九. 蓝本(Blueprint)

    概念: 当代码越来越多比较复杂的时候, 可以通过蓝本将对应功能的视图独立出来

    步骤:

    1. 新建一个文件user.py

      from flask import Blueprint
      #创建蓝本对象
      user = Blueprint('user',__name__)  # 第一个参数可看做该blueprint对象的姓名,姓名不能与其余的Blueprint对象姓名重复,第二个参数__name__用作初始化
      @user.route('/login/')
      def login():
          return '登录'
      @user.route('/loguut/')
      def logout():
          return '退出登录'
      
    2. 在主文件下添加如下代码

      from user import user
      # app.register_blueprint(user)  # 注册蓝本
      app.register_blueprint(user,url_prefix='/user') # 访问前缀, 访问的时候需要/user/login/
      

    拓展:

    (1) 蓝本和manage直接的跳转和参数的传递

    manage.py文件

    app = Flask(__name__)
    manage = Manager(app)
    @app.route('/')
    def index():
        return redirect(url_for('abcd.login'))
        return redirect(url_for('abcd.login',a=1,b=2))  # 带参数的蓝本跳转
    from user import user
    app.register_blueprint(user)  # 注册蓝本
    

    user.py文件

    user = Blueprint("abcd", __name__)  # 第一个参数 根据名字 找视图abcd.login
    @user.route('/login/<a>/<b>')  # 带参数的蓝本
    def login(a, b):
        print(a, b)  # 1 2   http://127.0.0.1/login/1/2
        return '登录'
    

    注意:

    1. 如果url_for()第二个参数传递的关键字参数(例如:name)名, 在反向构造函数(url_for调用的函数)中不存在则为aa/?name=xx, 如果存在则为aa/name/
    (2) 蓝本带前缀路由之间的跳转,manage->user user->manage

    manage.py文件

    @app.route('/test/')
    def test():
        # 如果添加一个login不存在的关键字a, 则地址为http://127.0.0.1/login/zs/?a=xx
        return redirect(url_for('user.login', name='zs'))
    
    app.register_blueprint(user, url_prefix='/user')  # 注册蓝本,带访问前缀
    

    user.py文件中

    @user.route('/login/<name>')
    def login(name):
        print(name)  # http://127.0.0.1/login/zs
        return '登录'
    

    九. 请求钩子函数

    概念: 类似于django的中间件, 写在蓝图中, 只针对蓝图的请求, 在蓝图中需要对应使用钩子函数

    钩子函数 功能描述
    before_app_first_request 第一次请求之前
    before_app_request 每次请求之前
    after_app_request 每次请求之后(前提没有异常)
    teardown_app_request 每次请求之后

    实例:

    @user.route('/login/')
    def login():
        return '登录'
    @user.before_app_first_request
    def beforeAppFR():
        print('before_app_first_request')
    @user.before_app_request
    def beforeApp():
         #可以如下这样使用
        if request.path == '/login/' and request.method="GET": #当请求login视图的时候 如果为 get请求 则请求失败  只是添加一个过滤  确保数据传输和请求更加安全
            abort(404)
        print('before_app_request')
    @user.after_app_request
    def afterApp(response):
        print(response)
        print('after_app_request')
        return response
    @user.teardown_app_request
    def teardown(exception):
        print(exception)
        print('teardown_app_request')
    

    相关文章

      网友评论

          本文标题:(一) flask入门介绍

          本文链接:https://www.haomeiwen.com/subject/mihiqftx.html