zoukankan      html  css  js  c++  java
  • Flask-路由和视图

    趁着这假期的时间,把这flask回顾回顾,

    一、Hello Flask

    #1.从flask模块导入了Flask类
    from flask import Flask
    
    #2.创建flask对象
    #参数1: __name__,如果从当前文件启动,那么值是__main__, 如果是从其他模块调用运行的那么值是模块的名字
    #参数2: static_url_path,表示静态资源的访问地址, /static
    #参数3: static_folder, 用来存储静态资源的,默认名字是static
    #参数4: template_folder, 模板文件夹,默认的值是templates
    app = Flask(__name__)
    print(__name__)
    print(app.static_url_path)
    print(app.static_folder)
    print(app.template_folder)
    
    #使用app,通过路由绑定一个视图函数
    #注意点: 视图函数一定要有返回值
    @app.route('/')
    def hello_world():
        return "hello world Flask"
    
    #判断是否直接使用当前模块运行程序
    if __name__ == '__main__':
        #运行app程序
        app.run()
    

    二、url_map

    查看哪些路由(地址)可以访问

    格式: 使用app.url_map, 返回的是app装饰的所有的路由和路径之间的映射关系

    注意: 只有被app.url_map包含进来的路由(地址)才能被访问

    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/index')
    def index():
        return "this is index"
    
    @app.route("/index2")
    def index2():
        return "this is index2"
    
    print(app.url_map)
    
    if __name__ == '__main__':
        app.run()
        
    # Map([<Rule '/index2' (GET, OPTIONS, HEAD) -> index2>,
    #  <Rule '/index' (GET, OPTIONS, HEAD) -> index>,
    #  <Rule '/static/<filename>' (GET, OPTIONS, HEAD) -> static>])
    
    

    三、app.run()

    • 参数1: host, 如果我们不指定,默认值是127.0.0.1
    • 参数2: port, 如果我们不指定,默认的值是5000
    • 参数3: debug,调试模式,如果不指定,默认的值是False
      • 如果设置为True,两个好处
      • 1.如果在运行的过程中,直接改动代码了,不需要重新启动程序,只需要ctrl+s保存即可部署程序
      • 2.如果程序报错了,会有友情提示

    如果参数3写了没有生效的话,直接在Pycharm中设置就行

    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/haha')
    def hello_world():
    
        #print(1/0)
    
        return "<h1>helloworld</h1>"
    
    if __name__ == '__main__':
    
        app.run(host="127.0.0.1",port=5001,debug=True)
    

    四、指定参数

    在访问路由的时候指定参数

    • 格式: @app.route("/<类型:变量名>")
    • 常见的参数类型
      • 整数 int
      • 小数 float
      • 字符串 path(默认就是path)
    from flask import Flask
    
    app = Flask(__name__)
    
    #接收一个整数
    @app.route('/<int:number>')
    def get_intnumber(number):
    
        return "the int is %s"%number
    
    #接收一个小数
    @app.route('/<float:number>')
    def get_floatnumber(number):
    
        return "the float is %s"%number
    
    #接收一个字符串
    @app.route('/<path:number>')
    def get_pathnumber(number):
    
        return "the path is %s"%number
    
    
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    五、自定义转换器

    背景:

    • 如果系统提供的int,float,等参数类型满足不了需求的时候,我们需要自定义

    • 之所以,int,float,path可以接收不同的数据类型,是因为,系统已经提供好对应的转换器了

    • 自定义转换器格式

      • 1.定义类,继承自BaseConverter
      • 2.重写init方法
      • 3.初始化父类成员变量, 还有子类自己的规则
      • 4.将转换器类,添加到系统默认的转换器列表中

      需求: 接收三位整数

    from flask import Flask
    from werkzeug.routing import BaseConverter
    
    app = Flask(__name__)
    
    
    # - 1.定义类,继承自BaseConverter
    class MyRegexConverter(BaseConverter):
        #这样直接指定规则,不够灵活,具体应该匹配什么规则应该交给路由
        # regex = "d{3}"
    
        # - 2.重写init方法,接收两个参数
        def __init__(self,map,regex):
            # - 3.初始化父类成员变量, 还有子类自己的规则
            super(MyRegexConverter, self).__init__(map)
            self.regex = regex
    
    # - 4.将转换器类,添加到系统默认的转换器列表中
    app.url_map.converters["re"] = MyRegexConverter
    
    #打印输出所有的系统转换器列表
    print(app.url_map.converters)
    
    #匹配三位整数
    #使用re('规则'),实际上是传递了两个参数,参数1: app.url_map,  参数2:括号中写的正则规则
    @app.route('/<re("d{3}"):number>')
    def hello_world(number):
    
        return "the three number is %s"%number
    
    #匹配四位整数
    @app.route('/<re("d{4}"):number>')
    def get_four_number(number):
    
        return "the four number is %s"%number
    
    #匹配一个手机号
    @app.route('/<re("1[3-9]d{9}"):phone>')
    def get_phone_number(phone):
    
        return "the phone number is %s"%phone
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    六、增加请求方式

    格式: @app.route('路径',methods=['请求方式1','请求方式2',....])

    • 常见的请求方式:
      • GET,POST,PUT,DELETE
    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/',methods=["POST","GET"])
    def hello_world():
    
        return "helloworld"
    
    if __name__ == '__main__':
        print(app.url_map)
        app.run(debug=True)
    

    七、返回响应(字符串)

    • 直接返回响应体数据
      • return '字符串'
    • 直接返回响应体数据+状态码
      • return '字符串',转台码
    • 直接返回响应体数据+状态码+响应头信息
      • return '字符串',转台码,{'key':'value'}
    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/')
    def hello_world():
    
        # - 1.直接返回响应体数据
        #     return 'helloworld'
    
        # - 2.直接返回响应体数据+状态码
        #     return 'helloworld',666
        #     return 'helloworld',"666 BIGERROR"
    
        # - 3.直接返回响应体数据+状态码+响应头信息
            return 'helloworld', 200, {"Content-Type": "application/json", "name": "pony"}
    
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    八、返回json数据

    • 格式: jsonify(dict)
    • 简化格式: jsonify(key=value,key2=value2)
    from flask import Flask, jsonify
    
    app = Flask(__name__)
    
    @app.route('/')
    def hello_world():
    
        #1.定义字典
        dict = {
            "name":"banzhang",
            "age":29
        }
        #2.返回json数据
        # return jsonify(dict)
    
        #3.返回json数据简化格式
        return jsonify(name="pony", age=20)
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    九、重定向

    • 格式: redirect('地址'), 地址既可以是本地服务器的地址,也可以是其他服务器的地址
    • 注意点: 重定向的代号是302
    • 特点: 重定向是两次请求
    from flask import Flask, jsonify, redirect
    
    app = Flask(__name__)
    
    @app.route('/index')
    def index():
        return redirect("/index2")
    
    @app.route('/index2')
    def index2():
        return "我是index2页面"
    
    if __name__ == '__main__':
        app.run()
    
    

    或者跳转到其他的页面

    from flask import Flask, redirect
    
    app = Flask(__name__)
    
    @app.route('/jingdong')
    def jingdong():
    
        #跳转到淘宝去
        return redirect("http://www.taobao.com")
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    十、url_for

    • 解释: 称为反解析,返回的是视图函数对应的路由地址

    • 格式: url_for('视图函数',key=value)

      注意点: url_for经常配合redirect使用,传递参数

      重定向到视图函数,并携带参数

    from flask import Flask, url_for, redirect
    
    app = Flask(__name__)
    
    @app.route('/jingdong')
    def jingdong():
    
        print(url_for("taobao",token=123))
        #1.通过url_for找到taobao的地址, 然后通过redirect,进行重定向
        response =  redirect(url_for("taobao",token=123))
    
        #2.返回响应体对象
        return response
    
    @app.route('/yamaxun')
    def yamaxun():
        #1.通过url_for找到taobao的地址, 然后通过redirect,进行重定向
        response =  redirect(url_for("taobao",token=456))
    
        #2.返回响应体对象
        return response
    
    @app.route('/taobao/<int:token>')
    def taobao(token):
    
        if token == 123:
            return "欢迎京东用户,给你打5折"
        elif token == 456:
            return "欢迎亚马逊用户,给你打9折"
        else:
            return "欢迎其他网站用户,给你9.9折"
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    十一、abort&errorhandler,异常处理

    • 使用场景: 当访问服务器资源的时候,如果找不到该资源,可以报出异常信息,使用errorhandler捕捉
    • 格式: abort(代号)
    • 格式: @app.errorhandler(代号)

    abort,异常抛出,主动抛出异常的状态码

    errorhandler,异常捕获,用来监听捕获异常并返回自定义的页面处理

    from flask import Flask, abort
    
    app = Flask(__name__)
    
    @app.route('/')
    def hello_world():
    
        abort(403)
    
        return "helloworld"
    
    #只要出现了404异常,就能捕捉
    @app.errorhandler(404)
    def page_not_found(e):
        print(e)
        return "<h1 style='color:red'>页面找不到</h1>"
    
    #只要出现了403异常,就能捕捉
    @app.errorhandler(403)
    def forrden(e):
        print(e)
        return "<h1 style='color:red'>禁止访问</h1>"
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    或者可以这样写

    from flask import Flask, request, abort,Response
     
    app = Flask(__name__)
     
     
    @app.route("/login", methods=["GET"])
    def login():
        name = ""
        pwd = ""
        if name != "zhangsan" or pwd != "admin":
            """
                使用abort函数可以立即终止视图函数的执行
                并可以返回给前端特定的信息
                1. 传递状态码信息,必须是标准的http状态码
                可以接受状态码信息,返回给前端已经默认好的信息
            """
            abort(404)
            """
                2. 传递响应体的信息, Response()里面的内容会在前端上显示出来
                resp = Response("login failed")
                abort(resp)
            """
        return "login success"
     
     
    """自定义异常处理"""
    @app.errorhandler(404)
    def handle_404_error(error):  # 接受一个错误信息
        """自定义的处理404错误方法"""
        '''这个函数的返回值会是前端所看到的最终的结果'''
        return "出现了404错误,错误信息:%s"%error
     
     
    if __name__ == '__main__':
        app.run(debug=True)
    

    十二、 request对象参数

    • request.data: 获取的是非表单(ajax)以post,提交的数据
    • request.form: 获取的表单以post方式提交的数据
    • request.args: 获取的是问号后面的查询参数
    • request.method: 获取的请求方式
    • request.url: 获取请求的地址
    • request.files: 获取的是input标签中type类型为file的文件
    from flask import Flask, request
    
    app = Flask(__name__)
    
    @app.route('/')
    def hello_world():
    
        print(request.method)
        print(request.url)
        print(request.args)
        # print(request.args["name"]) #字典不建议使用[]的方式取值
        print(request.args.get("name")) #如果获取不到不会报错,返回None
        print(request.args.get("age",39)) #如果获取不到,设置一个默认值
    
        return "helloworld"
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    十三、加载app程序运行参数

    • 从配置类(对象)中加载
      • app.config.from_object(obj)
    • 从配置文件中加载
      • app.config.from_pyfile(file)
    • 从环境变量中加载(了解)
      • app.config.from_envvar(环境变量)
    • app.config: 表示app程序,运行所有的参数信息
    from flask import Flask
    
    app = Flask(__name__)
    # print(app.config)
    
    # 1.从配置类(对象)中加载
    class MyConfig(object):
        #调试模式
        DEBUG = True
    
        #mysql数据库配置
    
        #redis配置
    
        #session配置
    
    # app.config.from_object(MyConfig)
    
    # 2.从配置文件中加载,此时目录下创建一个COnfig.ini的文件
    # app.config.from_pyfile("Config.ini")
    
    # 3.从环境变量中加载
    app.config.from_envvar("FLASKING")
    
    @app.route('/')
    def hello_world():
    
        return "helloworld"
    
    if __name__ == '__main__':
        app.run()
    

    十四、请求钩子

    解释: 当访问正常视图函数的时候,顺带执行的方法

    在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要处理,比如:

    • 在请求开始时,建立数据库连接;
    • 在请求开始时,根据需求进行权限校验;
    • 在请求结束时,指定数据的交互格式;

    为了让每个视图函数避免编写重复功能的代码,Flask提供了通用设施的功能,即请求钩子

    常见的请求钩子有四种:

    1. before_first_request:在处理第一个请求前执行
    2. before_request:在每次请求前执行,在该装饰函数中,一旦return,视图函数不再执行
    3. after_request:如果没有抛出错误,在每次请求后执行
      • 接受一个参数:视图函数作出的响应
      • 在此函数中可以对响应值,在返回之前做最后一步处理,再返回
    4. teardown_request:在每次请求后执行,接受一个参数:用来接收错误信息
    from flask import Flask
    
    app = Flask(__name__)
    
    #before_first_request装饰的函数在第一次访问的时候执行,里面适合做初始化操作,比如,io文件读写
    @app.before_first_request
    def before_first_request():
        print("before_first_request")
    
    #before_request,每次请求前都执行,适合对请求参数做校验,访问统计
    @app.before_request
    def before_request():
        print("before_request")
    
    #after_request,视图函数执行之后,返回该方法,适合对返回值做统一处理,比如:返回统一的json数据格式
    @app.after_request
    def after_request(resp):
        print("after_request")
        resp.headers["Content-Type"] = "application/json"
        return resp
    
    #teardown_request,请求销毁之后,执行该方法,适合做异常信息统计
    @app.teardown_request
    def teardown_request(e):
        print(e)
        print("teardown_request")
    
    
    @app.route('/')
    def hello_world():
    
        return "helloworld"
    
    @app.route('/index')
    def index():
        return "index"
    
    
    if __name__ == '__main__':
        app.run(debug=True)
    # 第一次请求
    # before_first_request
    # before_request
    # after_request
    # teardown_request
    # 第二次请求
    # before_request
    # after_request
    # teardown_request
    
  • 相关阅读:
    C/C++——二维数组与指针、指针数组、数组指针(行指针)、二级指针的用法
    C/C++——C语言数组名与指针
    C/C++——C语言跳出多重循环方法
    知识储备——国际象棋术语中英文对照
    C/C++——C语言库函数大全
    C/C++——C语言常用库函数
    C/C++——[05] 函数
    C/C++——[04] 语句
    C/C++——[03] 注释
    C/C++——[02] 运算符和表达式
  • 原文地址:https://www.cnblogs.com/mengd/p/13757496.html
Copyright © 2011-2022 走看看