zoukankan      html  css  js  c++  java
  • flask 基础

    1,环境安装

      1, mkvirtualenv name -p python3
      2, pip install flask==1.0.3

    环境变量配置:一般不用,只用在部署项目时,

    export FLASK_APP=xx.py # 指定flask应⽤所在的⽂件路径
    export FLASK_ENV=development # 设置项⽬的环境, 默认是⽣产环境
    flask run -h 0.0.0.0 -p 8000 # 启动测试服务器并接受请求

    2,路由定义 

    1,路由一定要以‘/’开头
    2,可以通过app.url_map属性来获取所有路由(url资源段)
    3,可以通过method 方法指定参数来设置路由的请求方式
    
    自定义路由转换器
    1,自定义路由转换器类,继承BaseConverter
    2,定义属性regex,设置匹配规则
    3,添加自定义转换器

    示例代码:

    from flask import Flask
    
    app = Flask(__name__)
    
    # 1. URL必须以/开头
    # 3. 可以通过methods参数来设置路由支持的请求方式
    @app.route('/index', methods=['POST', 'GET'])
    def index():
    
        return "index"
    
    
    if __name__ == '__main__':
        # 2.可以通过app.url_map属性来获取所有的路由规则 (URL资源段 支持的请求方式 视图函数的标记)
        print(app.url_map)
        # for rule in app.url_map.iter_rules():
        #     print(rule.rule, rule.methods, rule.endpoint)
        app.run(debug=True)

    3,路由变量

      正则对路由变量进行格式过滤,失败会返回404,

    # 路由变量: 实现动态URL  让一个视图函数可以绑定"一类URL"
    # 获取某本书   GET  /books/(?P<pk>d+)
    
    # 路由变量格式:  /user/<路由变量的名称>
    
    
    from flask import Flask
    from werkzeug.routing import BaseConverter
    
    app = Flask(__name__)
    
    
    # @app.route('/user/<userid>')
    # def index(userid):  # 一旦定义了路由变量, 必须定义同名形参来接收路由变量的值
    #     print(userid)
    #     return "index"
    
    
    # 正则转换器: 对路由变量进行格式过滤  过滤失败会返回404
    # 格式: /user/<转换器名:路由变量>
    @app.route('/user/<int:userid>')  # int转换器: 要求路由变量必须能够转为int
    def user(userid):
    
        print(type(userid))
        return 'user'

    自定义转换器的使用: 

      1. 自定义转换器类 继承BaseConverter
      2. 定义属性regex, 设置匹配规则
      3. 添加自定义转换器
    # 所有的内置转换器都继承BaseConverter
    
    """自定义转换器
    1. 自定义转换器类 继承BaseConverter
    2. 定义属性regex, 设置匹配规则
    3. 添加自定义转换器
    """
    class MobileConverter(BaseConverter): # 自定义转换器类
        # 定义属性regex, 设置匹配规则
        regex = r'1[3-9]d{9}$'  # 规则不要添加开头的^
    
    # 添加自定义转换器  {转换器名: 转换器类}
    app.url_map.converters['mob'] = MobileConverter
    
    
    @app.route('/home/<mob:mobile>')  # 使用自定义的转换器
    def home(mobile):
        return 'home'
    
    
    if __name__ == '__main__':
        # 获取所有的转换器 {转换器名: 转换器类}
        # print(app.url_map.converters)
        app.run(debug=True)

    4,flask接收前端的4中方式

      1,查询字符串方式  request.args

     # 获取查询字符串 -> request.args 类字典对象
        # print(request.args.get('name'))

      2,获取form_data表单传参   request.form

    # 获取请求体-键值对(表单) -> request.form    类字典对象
        # print(request.form.get('username'))

      3,获取请求体传参  文本   request.data  |  request.json

     # 获取请求体-文本(json) -> request.data/request.json
        # print(request.data)  # bytes类型
        # print(request.json.get('name'))  # 会将json字符串自动转为字典

      4,获取请求体传参   文件  request.files

    # 获取请求体-文件(图片) -> request.files 类字典对象
        file = request.files.get('avatar')  # type: FileStorage
        # 将文件保存到本地
        # file.save('123.png')
        # 获取文件的二进制数据
        file_bytes = file.read()

    完整代码:

    from flask import Flask, request
    from werkzeug.datastructures import FileStorage
    
    app = Flask(__name__)
    
    
    @app.route('/', methods=['POST', 'GET'])
    def index():
        # 获取请求的URL
        # print(request.url)
        # 获取本次请求的请求方式
        # print(request.method)
        # 获取本次请求的请求头
        # print(request.headers)  # 类字典对象 可以像字典一样赋值和取值
        # print(request.headers.get('Host'))  # 建议使用get方法, 不存在会返回None, 不报错
    
        # 请求传递数据的方式 1> URL路径参数-> 路由变量 2> GET 查询字符串 xx?name=xx&age=20  3> POST 请求体 键值对(表单)/文本(json)/文件(图片) 4> 请求头 -> request.headers
    
        # 获取查询字符串 -> request.args 类字典对象
        # print(request.args.get('name'))
    
        # 获取请求体-键值对(表单) -> request.form    类字典对象
        # print(request.form.get('username'))
    
        # 获取请求体-文本(json) -> request.data/request.json
        # print(request.data)  # bytes类型
        # print(request.json.get('name'))  # 会将json字符串自动转为字典
    
        # 获取请求体-文件(图片) -> request.files 类字典对象
        file = request.files.get('avatar')  # type: FileStorage
        # 将文件保存到本地
        # file.save('123.png')
        # 获取文件的二进制数据
        file_bytes = file.read()
        print(file_bytes)
        return "index"
    
    
    if __name__ == '__main__':
        app.run(debug=True)
    View Code

    响应:

    1,访问静态文件步骤:

      1,将静态文件放入static文件夹中

      2,使用flask内置的静态文件路由进行访问  http://127.0.0.1:5000/static/s.jpg

    from flask import Flask
    app = Flask(__name__)
    
    if __name__ == '__main__':
        app.run(debug=True)

    注意:只要在与当前同级目录下建立static文件,然后将图片文件放入该文件加下,启动程序,访问/static/xxx.jpg便可以

     2, 后端模板渲染步骤:

      1,将模板放入template文件夹中,指定模板语言

      2,使用render_template函数进行渲染

      3,在模板语言中使用模板语言来替换

    @app.route('/',methods=["GET"])
    def index():
        keyword = 'hello'
        html_str = render_template('baidu.html',kw=keyword)
        return html_str

    template文件中html代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        你输入的内容为: {{ kw }}
    </body>
    </html>
    View Code

    3,自定义响应对象 (需要设置响应头的时候才使用自定义响应对象)

    @app.route('/demo1')
    def demo1():
    # 视图函数可以返回str、bytes类型数据,并且内部会自动包装为Response类型的响应对象
    # 1,创建自定义响应对象,需要设置响应头的时候
    response = make_response('demo1')
    # 2,设置响应头, 类字典对象
    response.headers['name'] = 'xxx'
    return response

    4,返回json数据  jsonify会将字典封装为json对象,并且将content_type设置为application/json  (访问浏览器进行测试)

    # 4, 返回json
    @app.route('/demo2')
    def demo2():
        dict = {'name':'sd'}
        #jsonify可以将字典,关键字参数封装成json对象返回给前端,并且将content_type设置为application/json
        return jsonify(dict)

    5,重定向 :设置响应状态为301/302,响应头Location:目标url

    def demo3():
        # return redirect('http://www.baidu.com')
        # return redirect('/demo2')  #直接访问本网站
    
        # 可以根据视图函数的变偶记获取对应的url的资源段
        # url = url_for('demo2')  #根据函数名找到对应的url
        # print(url)
    
        # 开发中一般这样使用,考虑url重构
        # return redirect(url_for('demo2'))
    
        url = url_for('demo4',userid = 11)  #传递的参数,先使用url_for获取访问函数demo4的url,然后进行重定向(可以拼接参数)
        return redirect(url)
    
    
    @app.route('/demo4/<userid>')
    def demo4(userid):
       return 'demo4_%s'%userid

    6,自定义状态码:return的三段参数(响应体,响应状态码,响应头)

    # 6自定义状态码
    @app.route('/demo5')
    def demo5():
        #设置自定义状态,第二个返回值,用于自定义交互规则,700密码错误等
        # return  三段参数 (响应体,状态码,响应头)
        # return ‘demo5’,700,{'name':'xxx'}
       return 'demo5',700

     7,状态保持(session和cookie)

      1,cookie

    from flask import Flask, make_response, Response, request
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        # 后端设置cookie: 设置响应头的set_cookie字段
    
        # 创建响应对象
        response = make_response('index')  # type: Response
        # 设置响应头  value值必须是str/bytes
        response.set_cookie('per_page', '10', max_age=86400)
    
        # 删除cookie数据   本质: max-age=0
        # response.delete_cookie('per_page')
        return response
    
    
    @app.route('/demo1')
    def demo1():
        # 获取cookie: 浏览器会自动携带cookie数据给服务器, 通过请求头的cookie字段
        per_page = request.cookies.get('per_page')  # 类字典对象
        print(per_page)
    
        return 'demo1'

      2,session  (flask的session默认是存储在浏览器的cookie中的)

    from datetime import timedelta
    from flask import Flask, session
    
    app = Flask(__name__)
    # 设置应用秘钥 用于对session数据进行签名
    app.secret_key = 'test'
    # 设置session的过期时间  默认为31天
    app.permanent_session_lifetime = timedelta(days=7)
    
    
    @app.route('/')
    def index():
        # 记录session数据  类字典对象
        session['userid'] = 11
        # 设置session支持过期时间
        session.permanent = True
        return "index"
    
    
    @app.route('/demo')
    def demo():
        # 获取session数据
        print(session.get('userid'))
    
        # 删除session数据 本质:max_age=0 设置过期时间为0
        session.pop('userid', None)
        return 'demo'

    if __name__ == '__main__': app.run(debug=True)

    注意:flask的session默认是存储在浏览器的session中的,只是经过简单的base64进行加密,使用时一般都要修改存储位置:设置方式如下

    from datetime import timedelta
    from flask import Flask, session
    from flask_session import Session
    from redis import StrictRedis
    
    app = Flask(__name__)
    
    # 设置session的配置
    app.config['SESSION_TYPE'] = 'redis'  # 设置存储系统
    app.config['SESSION_REDIS'] = StrictRedis(host='127.0.0.1', port=6379)  # 指定redis客户端
    app.config['SESSION_USE_SIGNER'] = True # 设置对session进行签名
    app.config['SECRET_KEY'] = 'test'  # 设置应用秘钥
    
    # 初始化组件
    Session(app)
    
    
    @app.route('/')
    def index():
        # 记录session数据  类字典对象
        session['userid'] = 11
        return "index"
    
    
    @app.route('/demo')
    def demo():
        # 获取session数据
        print(session.get('userid'))
    
        # 删除session数据
        # session.pop('userid', None)
        return 'demo'
    
    
    if __name__ == '__main__':
        app.run(debug=True

    8,flask对象初始化参数

    from flask import Flask
    import sys
    
    # 记录模块的查询路径  包含 项目目录, 解释器目录, 第三方包的安装目录
    print(sys.path)
    
    app = Flask(__name__,  # 导入名称, flask会根据该参数查询静态/模板文件存储路径
                # 官方建议直接使用__name__, 如果使用该值, 则会从当前文件所在的目录中查询静态/模板文件存储路径
                static_folder='static1',  # 设置静态文件的存储路径 ,
                static_url_path='/res/img',  # 设置静态文件的访问路径  /res/img/oldyang.jpg
                template_folder='templates'  # 设置模板文件的存储路径
                )
    
    @app.route('/')
    def index():
        return "index"
    
    print(index.__name__)
    
    
    if __name__ == '__main__':
        app.run(debug=True)

     9,异常

     请求钩子(相当于django的中间件)

    @app.before_first_request(第一个访问web应用会触发,初始化处理)

    @app.teardown_request(响应对象包装为Response对象后触发,无论是否异常都会触发,相当于fanilly)

     

     蓝图:

     上下文:

     装饰器wraps的使用:因为引用发生了变化

     flask的配置:

    通过app.config

     

    动态创建应用 ,(添加蓝图创建应用)

     缺点:重要配置容易泄露

    从环境变量中加载:

      先从对象中加载默认配置,再通过环境变量重载隐私配置

  • 相关阅读:
    HDU 6370 dfs+并查集
    牛客网暑期ACM多校训练营(第六场)G
    HDU 6351暴力枚举 6354计算几何
    2018 ACM 国际大学生程序设计竞赛上海大都会赛重现赛 A,D
    2018 百度之星 初赛 第六题 HDU6349
    HDU 6336 子矩阵求和
    HDU 6333 莫队+组合数
    BZOJ 2308 莫队入门经典
    Linux系统管理第一章
    2019年7月17日
  • 原文地址:https://www.cnblogs.com/wjun0/p/11827470.html
Copyright © 2011-2022 走看看