精华内容
下载资源
问答
  • Flask入门

    2020-06-23 19:50:08
    Flask入门 一、Flask框架的简介 Flask是当下流行的Web框架,它是用Python实现的。Flask显著的特点是:它是一个“微”框架。”微”意味着Flask旨在保持核心的简单,但同时又易于扩展。默认情况下,Flask 不包含数据库...

    Flask入门

    一、Flask框架的简介

    Flask是当下流行的Web框架,它是用Python实现的。Flask显著的特点是:它是一个“微”框架。”微”意味着Flask旨在保持核心的简单,但同时又易于扩展。默认情况下,Flask 不包含数据库抽象层、表单验证,或是其它任何已有多种库可以胜任的功能。然而,Flask 支持用扩展来给应用添加这些功能。众多的扩展提供了数据库集成、表单验证、上传处理、各种各样的开放认证技术等功能。Flask的这些特性,使得它在Web开发方面变得非常流行。

    二、MVC设计模式

    一种软件设计典范,用一种业务逻辑,使数据,界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面与用户交互的同时,不需要重新编写业务逻辑。
    MVC被独特的发展起来用于映射传统的输入,处理和输出功能在一个逻辑的图形化界面结构中
    核心思想:解耦
    优点:降低个模块之间的耦合性,方便变更,更容易重构代码,最大程度实现了代码的重用。

    MVC(Model,View,Controller)

    Model:用于封装与应用程序的业务逻辑相关的数据及对数据的处理方法,是Web应用程序中用于处理应用程序的数据逻辑部分,Model通常只提供功能性的接口,通过这些接口可以获取Model的所有功能。

    View:负责数据的显示和呈现,View是对用户的直接输出。

    Controller:负责从用户端收集用户的输入,可以看成提供View的反向功能,主要处理用户交互

    三、python中MVT

    MVT(Model,View,Templates)

    Model:用于封装与应用程序的业务逻辑相关的数据及对数据的处理方法,是Web应用程序中用于处理应用程序的数据逻辑部分,Model通常只提供功能性的接口,通过这些接口可以获取Model的所有功能。

    Templates:负责数据的显示和呈现,View是对用户的直接输出。

    View:负责从用户端收集用户的输入,可以看成提供View的反向功能,主要处理用户交互

    四、WEB架构

    (1) B/S 浏览器->服务器

    WEB网站

    (2) C/S 客户端->服务器

    QQ

    五、Flask框架俩大核心

    Werkzeug 和 Jinja2

    Werkzeug:实现路由 调试 和 web服务器网关接口

    Jinja2:实现了模板(是flask核心开发组成员开发的)

    六、Flask的简单入门使用

    (1) 安装

    pip install flask

    (2) 启动完整程序

    实例:

    from flask import Flask
    #实例化flask类 传入必传参数 __name__ import_name
    app = Flask(__name__)
    
    # 添加路由
    @app.route('/')
    def index():
        return 'Hello Flask'
    
    
    # 运行
    if __name__ == '__main__':
        app.run()
    

    注意:

    假如在运行flask项目过程中 出现地址被占用 那也就是说 之前开启的服务并没有死掉 那么你可以去杀死进程 或者关闭编辑器 在或者更改一下端口号 这些都可以解决这个问题

    端口不传 默认5000

    访问:

    http://127.0.0.1:5000/

    (3) 路由地址

    # 添加路由 装饰器  传参就是字符串 
    @app.route('/')
    def index():
        return 'Hello Flask'
    

    访问:

    主机:端口/

    (4) 启动参数

    参数 说明
    debug 是否开启调试模式 默认为False 开启后自动加载代码 并进行如调试
    threaded 是否卡其多线程 默认不开启
    port 端口号 默认5000
    host 指定主机 默认127.0.0.1

    app.run(host=‘0.0.0.0’,port=5001,debug=True,threaded=True)

    当将主机设置为0.0.0.0 意味着可以使用IPV4或者127.0.0.1/localhost进行访问 如果不设置0.0.0.0 只能localhost/127.0.0.1进行访问

    七、视图参数

    (1) 无参路由

    # 添加路由
    @app.route('/')
    def index():
        return 'Hello Flask'
    

    (2) 路由地址结尾/的实例

    无/作为结尾

    # 创建test路由
    # 访问地址为 127.0.0.1:5000/test
    @app.route('/test')
    def test():
        return '我是test路由地址'
    

    访问:

    http://127.0.0.1/test

    有/作为结尾

    # 创建test路由
    @app.route('/test/')
    def test():
        return '我是test路由地址'
    

    访问:

    • http://127.0.0.1/test(多一个301的重定向)
    • http://127.0.0.1/test/

    (3) 带一个参数的路由地址

    # 带一个参数的路由地址
    # 访问:
    # 127.0.0.1:5000/arg/lucky/
    @app.route('/arg/<name>/')
    def arg(name):
        return '你好:'+name
    

    访问:

    • http://127.0.0.1:5000/arg/lucky/

    (4) 带多个参数的路由地址

    # 带多个参数的路由地址
    # http://127.0.0.1:5000/args1/zhangsan/18/
    # http://127.0.0.1:5000/args1/zhangsan_18/
    @app.route('/args1/<name>/<age>/')
    @app.route('/args1/<name>_<age>/')
    def args1(name,age):
        return 'name:{} age:{}'.format(name,age)
    

    访问:

    • http://127.0.0.1:5000/args1/zhangsan/18/
    • http://127.0.0.1:5000/args1/zhangsan_18/

    (5) 传参类型的限定

    # 限定参数类型
    # 默认参数类型为字符串
    # 可以通过 int/float/path/string进行类型的限定 默认为string
    # @app.route('/test/<arg>/') #默认为字符串
    # @app.route('/test/<int:arg>/') #限定传参类型为整形 否则失败
    # @app.route('/test/<float:arg>/') # 限定传参类型为浮点 否则失败
    # @app.route('/test/<string:arg>/') # 传参不管什么类型 最终都为字符串
    @app.route('/test/<path:arg>/') # 会把分隔符/认为是参数的一部分 
    def test(arg):
        print(type(arg))
        print(arg)
        return '测试路由地址传参的类型'
    

    访问:

    • http://127.0.0.1:5000/lucky/
    • http://127.0.0.1:5000/18/
    • http://127.0.0.1:5000/1.1/
    • http://127.0.0.1:5000/lucky/
    • http://127.0.0.1:5000/lucky/18/man/

    注意:

    1. 路由地址和视图函数可以不重名

    2. return + 字符串的内容 目前所写的这种形势 只是为了进行简单的测试 那以后工作的时候 返回的都是渲染后的模板(html页面)

    3. 在定义路由地址的时候 如果结尾没有添加/作为结尾 那么在访问的时候 结尾也不能带/ 否则404访问不到

    4. 在定义路由地址的时候 如果结尾有/ 在访问的时候 路由地址可以有/也可以没有 都可以访问到 所以 创建路由地址的时候 建议都+/作为路由地址的结尾

    5. 参数的写法为 <参数的名称>

    6. 一个视图函数可以有多个路由地址

    7. 一个视图传递多个参数 使用路由地址的分隔符/进行分隔 或者使用参数_进行拼接

    8. 路由地址传递参数默认类型为字符串

    9. 可以通过int/string/float/path进行参数类型的限定

    10. 参数的限定格式为<限定符:参数名称>

    八、重定向 redirect

    作用:

    可以通过访问的地址跳转到另外一个地址(试图函数)

    导入:

    from flask import redirect,url_for

    要进行跳转的路由地址视图函数为

    # 添加首页视图
    @app.route('/')
    def index():
        return 'Hello Flask'
    
    # 带参的视图函数
    # http://127.0.0.1:5000/args/lucky/18/
    @app.route('/arg/<name>/<age>/')
    def args(name,age):
        return '我叫:{} 我今年:{}岁了'.format(name,age)
    

    (1) redirect使用实例:

    作用:通过给定的路由地址进行跳转访问

    # 测试redirect的使用
    @app.route('/test_redirect/')
    def test_redirect():
        # return '测试重定向的视图函数'
        # 重定向到首页
        return redirect('/')
        # 重定向到带参的视图函数 args 如果不给传递参数 则为404
        # return redirect('/args/')
        return redirect('/args/lucky/18/')
    

    注意:

    1. redirect跳转其实就是将你在浏览器访问的那个路由地址5000后面的粘贴过来就可以了(或者是将代码中的路由地址粘贴到redirect中 如果存在参数的位置 替换成参数即可)
    2. 如果重定向的路由地址发生了改变 则重定向跳转失败(重定向的地址是写死的 也就是说不是通过代码动态生成的)

    (2) url_for使用实例:

    作用: 可以通过视图函数名称 动态生成路由地址 (也就是会根据视图函数来动态生成路由地址 不论路由地址如何更改 都可以动态生成)

    # url_for的使用
    @app.route('/test_url_for/')
    def test_url_for():
        # return '测试动态生成路由地址'
        # 测试无参路由地址
        return url_for('index')
        # 测试带参路由地址的构造
        return url_for('args',name='lucky',age=18)
    

    (3) redirect 与 url_for 的组合使用

    实例:

    # redirect 与 url_for 的组合使用
    @app.route('/redirect_url_for/')
    def redirect_url_for():
        # return 'redirect 与 url_for 的组合使用'
        # return redirect(url_for('index'))
        return redirect(url_for('args',name='lucky',age=18))
    

    九、abort 终止

    概述:

    如果在视图函数处理过程中 出现了异常错误 可以使用abort函数 立即进行视图函数的终止

    传参:

    abort函数的传参为http标准的状态码 如 404/500 返回状态码对应的信息 如果传递的为http标准中不存在的状态码 则无任何实际意义

    类似于python中的raise

    导入:

    from flask import abort

    实例:

    from flask import Flask,abort
    # 测试abort函数的使用
    @app.route('/test_abort/')
    def test_abort():
        print('我是上面的代码')
        abort(500)
        print('我是下面的代码')
        return 'test_abort'
    

    注意:

    1. abort如果给定的状态码不存在 则跑出flask异常的错误信息
    2. abort和raise 都会正常执行上面的代码 下面的代码不在执行

    捕获抛出的状态码

    from flask import render_template
    
    # 捕获状态码(1.系统自己抛出的 2.手动人为抛出的)
    # 参数为要捕获的状态码
    @app.errorhandler(404)
    def page_not_found(e):
        # return '错误为:{}'.format(e)
        # return e
        # 渲染模板
        return render_template('page_not_fonnd.html')
    
    # 捕获500的状态码
    @app.errorhandler(500)
    def page_not_found(e):
        # return '错误为:{}'.format(e)
        # return e
        # 渲染模板
        return render_template('page_not_fonnd.html')
    

    注意:

    1. 不光可以捕获人为抛出的状态码 还可以捕获系统抛出的
    2. 参数为你要捕获的状态码 如果想捕获多个 那么就多写几个捕获的装饰器就可以啦

    十、请求 request

    作用:

    获取请求者所携带数据

    概述:

    浏览器发送到服务器的所有请求被flask接收以后 创建出request对象 request请求对象被用在视图函数中 获取请求的数据

    使用:

    from flask import request

    request请求对象的属性

    1. url 获取完整的请求URL
    2. base_url 去掉get参数的url
    3. host_url 只有主机IP和端口号的url地址
    4. host 返回主机和端口
    5. path 请求的路由地址
    6. method 请求的方法的类型
    7. remote_add 请求客户端的IP地址
    8. args 获取get传参
    9. form 获取form表单post方法请求的数据
    10. files 文件上传
    11. headers 存储所有请求头信息
    12. cookies 获取存储cookie信息
    13. json 获取传递过来的json数据

    请求地址

    http://127.0.0.1:5000/test_request/?name=lucky&age=18

    实例:

    from flask import Flask,request
    @app.route('/test_request/')
    def test_request():
        # print(request.url)
        # print(request.base_url)
        # print(request.host_url)
        # print(request.host)
        # print(request.path)
        # print(request.method)
        # print(request.remote_addr)
        # 不建议这样
        # print(request.args['name'])
        # print(request.args['age'])
        # 建议使用get方法
        # print(request.args.get('xxx','default默认值'))
        print(request.headers.get('User-Agent'))
        return 'test_request'
    

    如果获取get传递的多个参数 可以使用如下代码实现

    print(request.args.getlist('name'))
    print(request.args.getlist('name')[0])
    print(request.args.getlist('name')[1])
    

    请求地址:

    http://127.0.0.1:5000/test_request/?name=lucky&name=18

    十一、路由响应 response

    请求对象是框架创建的 响应对象是由我们程序员创建的

    (1) 一个简单的响应

    # 构造一个简单的响应(携带状态码)
    @app.route('/')
    def index():
        return 'index',404
    

    (2) 通过make_response构造响应

    需要导入:

    from flask import make_response

    @app.route('/make_response/')
    def test_make_response():
        res = make_response('我是make_response构造的响应',404)
        return res
    

    十二、会话控制cookie与session

    概述:

    我们的协议为http超文本传输协议 无状态协议 每一次的请求都是新的请求 所以通过cookie和session作为一个连续会话请求的状态的保持

    cookie

    简介流程图

    ​ 第一次

    客户端 -----》服务器

    ​ cookie

    客户端《-----服务器

    ​ 携带者cookie

    客户端 -----》服务器

    cookie值的存储

    cookie的值存储在客户端浏览器上 明文存储不安全 客户端的浏览器会限制单个站点cookie的个数为20个 并且单个cookie的保存值的大小不能超过4k

    (1) 设置cookie

    格式:

    response.set_cookie(key,value,max_age=None,expires=None)

    key:键

    value:值

    max_age:过期时间 秒为单位

    expires:以秒为单位的失效时间

    实例:

    # 设置cookie
    @app.route('/set_cookie/')
    def set_cookie():
        # 构造响应
        res = make_response('设置cookie')
        # 设置cookie
        res.set_cookie('name','lucky')
        return res
    

    设置成功后 可以在浏览器的网络进行点击查看 -->Response Headers

    默认过期时间为 浏览会话结束时 也就是关闭浏览器

    (2) 设置cookie并设置过期时间

    实例:

    #设置cookie并设置过期时间
    @app.route('/set_cookie_lifetime/')
    def set_cookie_lifetime():
        res = make_response('设置cookie并设置过期时间')
        # max_age 设置过期时间 给定的值为存活的秒数
        res.set_cookie('name','lucky',max_age=20)
        # 给定一个终止的时间戳
        expires = time.time()+20
        res.set_cookie('name','lucky',expires=expires)
        return res
    

    (3) 获取cookie

    实例:

    #获取cookie
    @app.route('/get_cookie/')
    def get_cookie():
        return request.cookies.get('name','默认值')
    

    (4) 删除cookie

    实例:

    #删除cookie
    @app.route('/del_cookie/')
    def del_cookie():
        res = make_response('删除cookie')
        # 删除key为name的cookie 第一种删除的方式
        # res.delete_cookie('name')
        # 第二种删除 重新设置 刚设置完就死掉了
        res.set_cookie('name','',expires=0)
        return res
    

    session

    概述:

    session将数据存储在服务器端 给客户端cookie唯一的sessionID号 通过客户端请求携带着唯一的session_id 进行获取对应的数据

    flask会将会话对象加密后存储在客户端的cookie中 因此必须要为应用实例的secret_key 属性配置一个加密种子 才能使用session

    实例:

    app.secret_key = '随机的字符串'
    app.config['SECRET_KEY'] = '随机字符串'
    

    导入:

    from flask import session

    实例导入与配置

    from flask import Flask,session
    app = Flask(__name__)
    # 添加配置参数
    app.config['SECRET_KEY'] = 'lucky is a good man'
    

    (1) 设置session

    实例:

    from flask import Flask,session
    # 设置session
    @app.route('/set_session/')
    def set_session():
        # 设置session
        session['name'] = 'lucky'
        return '设置session'
    

    默认存活时间为 浏览会话结束时 也就是关闭浏览器

    (2) 设置session及过期时间

    导入:

    from datetime import timedelta

    计算时间差值的累类参数都为时间

    实例:

    #设置session并设置过期时间
    @app.route('/set_session_lifetime/')
    def set_session_lifetime():
        # 设置session持久化存储
        session.permanent = True
        app.permanent_session_lifetime = timedelta(minutes=3)
        session['name'] = 'lucky'
        return '设置session及过期时间'
    

    (3) 获取session

    实例:

    #获取session
    @app.route('/get_session/')
    def get_session():
        return 'name的值为:{}'.format(session.get('name','默认值'))
    

    (4) 删除session

    实例:

    # 删除session
    @app.route('/del_session/')
    def del_session():
        # 删除指定的key
        # session.pop('name')
        # 移除所有session 适用于网站退出登录 删除所有session会话
        session.clear()
        return '删除session'
    

    cookie和session的区别

    1. cookie的数据存储在客户端浏览器上 session数据存储在服务器上
    2. cookie明文存储不安全 session比cookie更加安全
    3. session会在一定时间内保存数据在服务器上 当访问增多 会比较占用你服务器的性能 考虑到服务器的性能 可以将不重要的数据存储在客户端浏览器上 也就是cookie上
    4. 单个cookie保存的数据不能超过4k 很多浏览器会限制一个站点最多保存20个cookie

    所以lucky老师建议:

    将登录等重要的信息 存放在session中

    其它信息如果需要保留 建议存放在cookie中

    十三、flask-script扩展库

    安装:

    pip install flask-script

    简介:

    简单来说 就是一个flask终端运行解析器 因为在项目完成以后 最好不要更改任何代码 否则都会带来风险 所以借助扩展库实现启动 通过传递参数 完成不同的启动

    使用:

    from flask import Flask
    from flask_script import Manager
    
    app = Flask(__name__)
    # 实例化终端运行解析器
    manager = Manager(app)
    ...
    if __name == '__main__':
        manager.run()
    

    optional arguments:
    -?, --help show this help message and exit
    -h HOST, --host HOST
    -p PORT, --port PORT
    –threaded
    –processes PROCESSES
    –passthrough-errors
    -d, --debug enable the Werkzeug debugger (DO NOT use in production
    code)
    -D, --no-debug disable the Werkzeug debugger
    -r, --reload monitor Python files for changes (not
    100{‘option_strings’: [’-r’, ‘–reload’], ‘nargs’: 0,
    ‘const’: True, ‘metavar’: None, ‘default’: None,
    ‘type’: None, ‘required’: False, ‘prog’: ‘manage.py
    runserver’, ‘container’: <argparse._ArgumentGroup
    object at 0x7f7fbec11a58>, ‘help’: ‘monitor Python
    files for changes (not 100% safe for production use)’,
    ‘dest’: ‘use_reloader’, ‘choices’: None}afe for
    production use)
    -R, --no-reload do not monitor Python files for changes

    完整的访问参数为:

    python3 manage.py runserver -h0.0.0.0 -p5001 -d -r

    python manage.py runserver -d -r

    十四、蓝本 blueprint

    导入:

    from flask import Blueprint

    概述:

    当我们的代码越来越复杂的时候 将所有的视图函数放在一个文件中 很明显是不合适的 如果能够根据功能模块进行划分 存储在不同的文件中 那么蓝本就是未解决此问题而存在的

    使用实例:

    蓝本文件 user.py

    from flask import Blueprint # 导入蓝本
    
    
    # 参数1 user
    user = Blueprint('user',__name__)
    
    
    # 登录的视图函数
    @user.route('/login/')
    def login():
        return '登录'
    
    
    # 注册的视图函数
    @user.route('/register/')
    def register():
        return '注册'
    

    manage.py

    from flask import Flask
    from flask_script import Manager
    
    
    app = Flask(__name__)
    manager = Manager(app)
    
    
    @app.route('/')
    def index():
        return 'index'
    
    
    # 测试重定向跳转的视图函数
    @app.route('/test_redirect/')
    def test_redirect():
        return '测试重定向'
    
    
    # 导入蓝本对象
    from user import user
    # 注册蓝本
    # http://127.0.0.1:5000/login/
    app.register_blueprint(user)
    # 参数1为蓝本对象  参数2为访问蓝本路由的前缀 默认没有
    # http://127.0.0.1:5000/user/login/
    # app.register_blueprint(user,url_prefix='/user')
    
    
    if __name__ == '__main__':
        manager.run()
    

    蓝本文件的重定向

    实例:

    # 测试重定向跳转的视图函数
    @app.route('/test_redirect/')
    def test_redirect():
        # return '测试重定向'
        # 从manage 重定向到user
        # return redirect('/login/')
        # 使用url_for 构造路由 错误的写法
        # return url_for('login')
        # 需要告诉url_for是哪一个蓝本文件的login视图函数
        return url_for('user.login')
    

    注意:

    在构造蓝本文件路由地址的时候 需要告诉url_for是哪个蓝本文件的视图函数名称 否则构造失败

    展开全文
  • Flask 入门

    2019-07-01 18:12:19
    Flask 入门安装Flask创建一个Flask项目调试模式配置内容的加载路由1.最普通的模式2.路由传参3.URL变量可以使用转换器指定参数的类型4.自定义转换器类型;5.HTTP请求获取请求数据响应自定义报错内容 flask 官方文档 :...


    flask 官方文档 :http://flask.pocoo.org/docs/1.0/quickstart/
    环境: Python3.4 , Flask1.0.3

    一、安装Flask

    如果没有虚拟环境的话,可以先安装虚拟环境:

    sudo pip install virtualenv
    

    然后,创建一个新的虚拟环境:

    mkvirtualenv flask_py3 -p python3.4
    

    安装Flask

    pip install Flask
    

    pip list 查看安装了那些包;
    在这里插入图片描述

    二、创建一个Flask项目

    在这里插入图片描述

    在项目路径下创建一个py文件,
    在这里插入图片描述
    输入内容:

    from flask import Flask
    
    app = Flask(__name__) # 创建一个flask应用,但是必须指定程序所在包的名字 __name__
    
    
    @app.route('/') # 实现了路径与视图的绑定,第一个参数是路径
    def index():
        return 'hello world'
    
    
    if __name__ == '__main__':
        app.run()  # 启动web服务器
    

    运行程序效果:
    在这里插入图片描述

    三、调试模式

    上面的服务器是能开启来了,但是现在代码修改了之后并不能像Django那样进行自动更新,此时就需要配置成调试模式。

    1.直接在应用对象上设置:

    app.debug = True
    app.run()
    

    2.作为 run 方法的一个参数传入:

    app.run(debug=True)
    

    这俩种方法的实现效果一样。

    四、配置内容的加载

    1.写一个类,然后通过app.config.from_object() 来加载

    # 配置文件的设置
    class Config(object):
        DEBUG = True # debug调试模式开启
        PORT = 6000
        USERNAME = 'Tony'
    
    配置对象类加载进app
    app.config.from_object(Config)
    

    2.创建一个 config.ini 配置文件,在里面写一些配置内容,然后通过app.config.from_pyfile('config.ini')来加载

    config.ini 文件内容:
    在这里插入图片描述

    五、路由

    使用route()装饰器将函数绑定到URL:

    1.最普通的模式

    @app.route('/')
    def index():
        return 'hello world'
    

    2.路由传参

    # 路由传参
    @app.route('/user/<username>')
    def profile(username):
        return '{}\'s profile'.format(username)
    

    3.URL变量可以使用转换器指定参数的类型

    # 理由参数设为int类型
    @app.route('/post/<int:post_id>')
    def show_post(post_id):
        return 'Post %d' % post_id
    

    自带的转换器类型:
    在这里插入图片描述

    • string :(默认值)接受任何没有斜杠的文本
    • int : 接受正整数
    • float : 接受正浮点值
    • path : 像字符串,但也接受斜杠
    • uuid : 接受UUID字符串

    4.自定义转换器类型;

    from werkzeug.routing import BaseConverter # 转换器
    
    # 进行转换器的重写
    class MyCover(BaseConverter):
        def __init__(self, parm, *args):
            print(*args) # 获取自己写的正则
            super().__init__(parm)
            self.regex = args[0] # args第一个参数就是正则表达式
            
    # 将自定义的转换器加入到转换器字典中去
    app.url_map.converters['re'] = MyCover
    
    # 自定义路径转换器
    @app.route('/text/<re("[\w]+"):text>')
    def mytext(text):
        return '{}\'s profile'.format(text)
    

    测试结果:
    在这里插入图片描述

    5.HTTP请求

    默认情况下,路由仅GET响应请求。route()的methods参数可以处理不同的HTTP方法。

    from flask import request
    
    # http 请求
    @app.route('/login', methods=['GET', 'POST']) # 大小写都行
    def login():
        if request.method == 'POST':
            return '这是一个登入页面,POST请求'
        else:
            return '这是一个GET请求'
    

    六、获取请求数据

    获取请求头:request.headers
    获取GET请求中的数据:request.args
    获取请求中的表单数据: request.form
    获取请求中的表单数据里面的文件:request.files
    获取请求中的json数据: request.json
    获取请求中的数据: request.data

    区别:
    1.request.json需要application/json的mimetype类型。

    2.当minitype为application/x-www-form-urlencoded或者multipart/form-data的时候,也就是表单提交,访问 request.form会返回一个包含解析过的的表单对象的 MultiDict,而request.data是空的。

    3.当flask遇到不能处理的mimetype时,请求的数据就不能被其它方式正常解析,这些方式包括 request.formrequest.jsonrequest.files这几个常用的用来访问数据的属性。这时就把数据作为字符串存在request.data中。

    七、响应

    不能返回 dict 字典类型,只能是string,tuple等类型,所以用flask带的jsonify转换json类型然后返回

    from flask import jsonify
    
    @app.route('/', methods=['POST', 'GET']) # 实现了路径与视图的绑定,第一个参数是路径
    def index():
        if request.method == 'GET':
            print(app.config.get('DEBUG'))
            print(app.config.get('USERNAME'))
            print(app.url_map) # 获取url的路径
            data = {
                'name': '小米',
                'age': 18
            }
            return jsonify(data)
    

    八、自定义报错内容

    1.第一种方法

    from flask import render_template
    
    @app.errorhandler(404)
    def page_not_found(error):
        return render_template('page_not_found.html'), 404  # 这里的404是返回给前端的状态码
    

    page_not_found.html 的内容:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>404 页面找不到</h1>
    </body>
    </html>
    

    效果图:
    在这里插入图片描述

    2.第二种方法

    from flask import abort # 抛出错误
    
    @app.route('/', methods=['GET', 'POST'])
    def index():
        abort(404) # 手动抛出错误
        return 'ok'
    
    @app.errorhandler(404)
    def page_not_fount(e):
        return 'This page does not exist', 404
    

    效果图:
    在这里插入图片描述

    九、cookie的设置和获取

    1.cookie 的设置

    from flask import make_response
    
    @app.route('/setcookie')
    def setcookie():
        response = make_response('ok')
        response.set_cookie('asdf', '123456')
        return response
    

    2.cookie 的获取

    from flask import request
    
    @app.route('/getcookie')
    def getcookie():
        print(request.cookies)
        data = request.cookies
        return '获取成功'
    

    效果图:
    在这里插入图片描述

    十、session的设置和获取

    注意:

    • cookie 存着 session 的id
    • session 依赖于 cookie

    1.session的设置

    from flask import session
    import os
    
    app.secret_key = os.urandom(24)
    
    @app.route('/setsession')
    def setsession():
        session['name'] = '隔壁老王'
        print(app.secret_key)
        return 'session is ok'
    

    2.session的获取

    @app.route('/getsession')
    def getsession():
        data = session.get('name')
        print(session)
        return data
    

    效果图:
    在这里插入图片描述

    展开全文
  • flask入门

    2019-09-03 23:21:11
    一、Flask简介 Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。Flask使用 BSD 授权。 Flask也被称为 “microframework” ,因为它使用简单的核心,用 ...

    一、Flask简介
    Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。Flask使用 BSD 授权。Flask也被称为 “microframework” ,因为它使用简单的核心,用 extension 增加其他功能。Flask没有默认使用的数据库、窗体验证工具。
    二、Flask作用
    Flask有很多拓展功能可以使用,可以自由的决定设计的目标,Flask会一直提供一个非常简约而优秀的胶合层。可以自由地使用SQLAlchemy执行高级模式,或者使用其他数据库工具,亦可引入非关系数据模型,甚至还可以利用用于Python网络接口WSGI的非框架工具。
    三、有关操作
    1.栈Stack:
    flask中的请求数据存放是利用列表构造的栈来存储的,每次pop都从最后pop出栈。,特点是后进先出,用栈的好处就是当取出栈中最后一个元素处理时,之前所存入的元素已经准备就绪,不会发生混乱情况。具体代码及解释如下:

    class Stack():
        def __init__(self,size):
            self.size=size
            self.stack=[]####用列表表示栈,遵循后进先出原则
            self.top=-1###从栈顶取元素
        def push(self,x):###向栈中添加元素
            if self.isfull():###判断栈是否已经满
                raise exception("stack is full")
            else:
                self.stack.append(x)###将x元素加入到栈里边
                self.top=self.top+1   #["a"] self.top= 0 ["a","b"] self.top=1
        def pop(self):###从栈中取出元素
            if self.isempty():###判断栈是否是空
                raise exception("stack is empty")
            else:
                self.top=self.top-1
                self.stack.pop()###从栈顶取出元素  pop():默认取出一个元素
        def isfull(self):
            return self.top+1 == self.size###栈的大小
        def isempty(self):
            return self.top == '-1'
        def showStack(self):
            print(self.stack)
    s=Stack(10)##栈的大小为10
    for i in range(6):
        s.push(i)###向栈中添加元素i(0-5)
    print(s.showStack())
    for i in range(3):####依次从栈顶取出3栈顶个元素
        s.pop()
    print(s.showStack())
    

    运行结果

    [0, 1, 2, 3, 4, 5]
    None
    [0, 1, 2]
    None
    

    2.队列Queue(代入)
    和栈相同,只不过遵循先进先出的原则,具体代码如下:

    class Queue():
        def __init__(self,size):
            self.size=size
            self.putnum =-1
            self.getnum =-1
            self.queue=[]
        def put(self,element):
            if self.isfull():
                raise exception("queue is full")
            else:
                self.queue.append(element)
                self.putnum=self.putnum+1
        def get(self):
            if self.isempty():
                raise exception("queue is empty")
            else:
                self.queue.pop(0)
                self.getnum=self.getnum+1
        def isfull(self):
            return self.putnum-self.getnum+1 == self.size
        def isempty(self):
            return self.putnum == self.getnum
        def showQueue(self):
            print(self.queue)
    q=Queue(10)
    for i in range(6):
        q.put(i)
    q.showQueue()
    for i in range(3):
        q.get()
    q.showQueue()
    

    运行结果

    [0, 1, 2, 3, 4, 5]
    [3, 4, 5]
    

    3.本地代理,上下文,将上下文压入栈,ctx初始化时设置了两个重要属性request,session。用偏函数将对象属性设定,提取对象属性值,将一些属性加入本地栈中,可以在栈中直接访问,提取对象元素,实现代码如下:

    from functools import partial
    class HttpRequest(object):
        def __init__(self):
            self.method = "GET"###创建对象属性"get"
            self.body = b"name=abc@age=123"
        def __getitem__(self, item):
            return  self.__dict__[item]
    class RequesttContext(object):
        def __init__(self):
            self.request = HttpRequest()
            self.session = {"login":True,"is_super":False}
        def __getitem__(self, item):###传入参数item,后续可以不传入
            return self.__dict__[item]
    reqcxt=RequesttContext()###上下文
    def func(args):
        return getattr(reqcxt,args)
    re_func = partial(func,'request')###等价于re_func():HttpRequest(),返回值就是HttpRequest()
    se_func = partial(func,'session')  ###等价于se_func():{"login":True,"is_super":False},返回字典
    class LocalProxy(object):
        def __init__(self,local):
            self._local = local
        def _get_current_object(self):
            print(self._local,self._local())
            return self._local()
        def __getitem__(self, item):
            return getattr(self._get_current_object(),item)
    request = LocalProxy(re_func)###等价于request1 = HttpRequest()###直接在本地代理中提取出request,相当于一个接口,返回re_func
    ret = request['method']
    print(ret)
    session = LocalProxy(se_func) #local={"login":True,"is_super":False}
    print(session._get_current_object())
    

    运行结果

    functools.partial(<function func at 0x7f0a05574e18>, 'request') <__main__.HttpRequest object at 0x7f0a036568d0>
    GET
    functools.partial(<function func at 0x7f0a05574e18>, 'session') {'login': True, 'is_super': False}
    {'login': True, 'is_super': False}
    

    4.本地线程
    4.1

    import time
    import threading
    class A:
        pass
    local = A()
    def func(n):
        local.val = n
        time.sleep(1)
        print(local.val)
    for i in range(10):
        t = threading.Thread(target=func,args=(i,))
        t.start()
    

    运行结果

    9
    9
    9
    9
    9
    9
    9
    9
    9
    9
    

    原因分析:在多线程中,同一个进程中的多个线程是共享一个内存地址的,多个线程操作数据时,就会造成数据的不安全,需要线程私有化,实现代码如下
    4.2线程私有化

    import time
    import threading
    class A:
        pass
     local = threading.local()###线程私有化
    def func(n):
        local.val = n
        time.sleep(1)
        print(local.val)
    for i in range(10):
        t = threading.Thread(target=func,args=(i,))
        t.start()  
    

    运行结果

    0
    1
    2
    3
    5
    7
    4
    6
    9
    8
    

    5.栈的存取
    栈的隔离技术(一个线程对应一个栈)

    from threading import current_thread as getcurrent
    class Local(object):
    def __init__(self):
        object.__setattr__(self,"_storage",{})
    def __setattr__(self, key, value):
        ident = getcurrent()###定制粒度更细的
        if ident in self._storage:
            self._storage[ident][key] = value
        else:
            self._storage[ident] = {key:value}
    def __getattr__(self, item):
        ident = getcurrent()
        return self._storage[ident][item]
    class LocalStack(object):
        def __init__(self):
            self.local = Local()
        def push(self,item):
            self.local.stack = []
            self.local.stack.append(item)
        def pop(self):
            return self.local.stack.pop()
        def top(self):
            return self.local.stack[-1]
    _local_stack = LocalStack()
    _local_stack.push(55)###向栈中加入元素
    print(_local_stack.top())###取出栈顶元素
    

    6.简易版Flask框架

    from wsgiref.simple_server import make_server
    ViewFunctions = {}
    def wapper(name):
        def _wapper(f):
            ViewFunctions[name] = f
            return f
        return _wapper
    @wapper("/wang")
    def home():
        return [b'<h1>Hello, web!</h1>']
    @wapper("/favicon.ico")
    def pic():
        return [b'<h1>pic!</h1>']
    print(ViewFunctions)
    class Flask:
        def __init__(self):
            self.view_functions = {}
        def __call__(self,environ, start_response):
            key = environ['PATH_INFO']
            print(key)
            start_response('200 OK', [('Content-Type', 'text/html')])
            return ViewFunctions[key]()
    application = Flask()
    httpd = make_server('', 8000, application)
    #开始监听http请求
    httpd.serve_forever()
    
    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,153
精华内容 1,661
关键字:

flask入门