python_flask_路由

1、基本定义

  • app.rout()中参数methods设置请求参数使用(不区分大小写)
  • #添加get post 请求方式
    @app.route("/", methods=["get", "post"])
  • 指定访问路径访问‘/demo1’
  • @app.rout("/demo1")
    def demo1():
        return "demo1"
  • 给路由传参“/demo2/<user_id>”(默认出入的参数是string类型)
  • @app.route('/demo2/<user_id>')
    def demo2(user_id):
        # 返回传入参数
        return user_id
    
  • 传入指定参数:@app.route("/demo3/<int:user_id>")
  • # 使用转换器设置传入参数类型只能为int
    @app.route('/dome3/<int:user_id>')
    def demo3(user_id):
        # 返回user_id
        return user_id
  • 系统自带转换器有(具体类型查看源代码的正则匹配规则)(string:字符串;int:整形 ;float:小数;path:地址)
  • DEFAULT_CONVERTERS = {
        'default':          UnicodeConverter,
        'string':           UnicodeConverter,
        'any':              AnyConverter,
        'path':             PathConverter,
        'int':              IntegerConverter,
        'float':            FloatConverter,
        'uuid':             UUIDConverter,
    }
  •  返回json类型的数据类型:jsonify() 需要导入相关模块(可以使用ALT键+回车快速导入)
  • @app.route('/demo4')
    def demo4():
        josn_1 = {
            'mane':'li'
            'age':18
        }
        # 使用jsonify()将数据类型转换成json
        return jsonify(josn_1)
        # 不推荐使用json。dumps转换成json类型的字符串,
        # 因为http传josn类型的数据需要设置conttent_type:application/json,
  • 重定向某个网址:redirect(" url ") (需要导入相关模块(alt+Enter))
  • @app.route('/demo5')
    def demo5():
        # 重定向到百度
        return redirect('http://www.baidu.com')
  •  重定向到自己的视图函数:(可以写url,也可以使用url_for()指定视图函数对应的的url)
  • @app.route("/demo6")
    def demo6():
        # 重定向到自己的视图函数demo1
        #(url_for()传入的参数是视图函数的函数名不是路由)   
        return redirect(url_for('demo1'))
  •  重定向到带参数的视图函数
  • @app.route("/demoa/<int:user_id>")
    def demoa(uesr_id):
        return user_id
        
    
    @app.route("/demo7")
    def demo7():
        # url_for第二个参数写需要传入的参数
        return redirect(url_for('demoa', user_id = 100))
  •  自定义状态码
  • @app.route('/demo8')
    def demo8():
        # 使用return返回时,第二个参数写自定义的需要返回的状态码
        return '返回状态码', 666
  • 使用正则匹配路由
    • 首先需要自定义一个转换器,然后将自定义的转换器以"re"添加到转换器字典中,并再路由中使用"re"调用
  • #首先导入BaseConveruer模块(可以使用ALT+Enter快速导入)
    from werkzeug.routing import BaseConverter
    
    #自定义转换器
    class RegexConverter(BaseConverter):
        def __init__(self, url_map, *args):
            # 调用父类的init函数,完成初始化
            super(RegexConverter, self).__init__(url_map)
            # 使用不定长参数传入自己定义的正则表达式
            self.regex = args[0]
    
    
    # 将自定义的转换器添加到转换器字典中,并定义为‘re’
    app.Flask(__name__)
    
    app.url_map.converters['re'] = RegexConverter
    
    # 使用自定义转换器自定义匹配规则
    # (自定义规则使用‘re’定义规则;参数名以‘id‘传入到视图函数)
    @app.route('/demo9/<re([0-9]{4}):id>')
    def demo9(id):
        return id

2、捕获异常

  • 抛出异常abort()方法(需要导入baort模块)
  • from flask import abort
    
    @app.route("/demoa")
    def demoa():
        # 请求'/demoa'时主动抛出一个500的异常
        abort(500)
  • 捕获抛出的某个特定状态码的异常
  • # 捕获异常需要用到errorhandler装饰器
    # 捕获状态码为500的异常,较友好的提醒用户错误 
    @app.errorhandler(500)
    # 设置参数e用于接受异常
    def demo10(e):
        return "出错了"
  • 捕获指定异常
  • # 当发生ZerDivisionError时自动捕获异常并返回交友好的提示
    @app.errorhandler(ZerDivisionError)
    # 设置参数e用于接受异常
    def demo12(e):
        # 当发生该异常时返回"发生除数错误"提示
        return "除数不能为0"

3、请求钩子

  • efore_first_requset 处理第一次请求前执行(仅执行一次)
  • @app.before_first_request()
    def demo13():
        # 可以在此处执行设置链接数据库参数等操作
        print ("before_first_request") 
  • before_request 处理每次请求前执行(每次请求前执行一次)
  • @app.before_request()
    def demo14():
        print('before_request')
        ‘’‘
            可以在此处设置验证ip是否在黑名单中
            如果此处有return则其他视图函数不会执行,
            而直接返回return后面的东西
        ’‘’
        # return "就不让访问"
  • after_request 每次请求之后执行并且没有异常抛出时执行((执行某些操作以及可以对响应做最后处理)需要接受一个响应作为参数,并且返回需要返回该响应)
  • @app.afetr_request()
    def demo14(response):
        # 打印该响应
        print(response)
        # 设置响应的Content-Type为application/json"
        response.headers["Content-Type"] = "application/json"
        return request
  • teardown_request 在每次请求后执行(需要有一个参数接收该异常)
  • @app.teardown_request()
    def demo16(e):
        print('teardoen_request')
        # 如果没有异常e为None
        if e:
            print (e)

4、获取请求参数

  • data:记录请求的数据并转换为字符串,类型:*
  • form:记录请求中的表单数据,类型:MultiDict
  • args:记录请求中的查询参数,类型:MultiDict
  • files:记录请求上传的文件,类型:*
  • cookies:记录cookis中的信息,类型:Dict
  • method:记录请求中的HTTP请求方法,类型:GET/POST/...
  • headers:记录请求报文中的报文头,类型:EnvronHeaders
  • url:记录请求的URL地址,类型:string
  • 常用示例:
  • # 将 GET,POST 加入到请求方式中
    @app.route("/demo12", methods=["get", "post"])
    def demo12():
        # 获取通过url中传入的参数如:http://127.0.0.1:5000/demo12?mane=qwe
        # 中"?"后的name=qwe
        # 打印结果如:ImmutableMultiDict([('mane', 'qwe')])
        if request.args:
            print(request.args)
        # 获取从form表单中提交的数据
        # 打印结果如:ImmutableMultiDict([('asd', 'asd')])
        if request.form:
            print(request.form)
        # 获取请求数据
        # 打印结果如:b'qweqwe'
        if request.data:
            print(request.data)
        # 获取json类型的数据
        # 打印结果如:{'name': 'nihao'}
        if request.json:
            print(request.json)
        # 获取传入文件pic,并打印该文件名,并保存为12.png
        # 打印结果如下:第一行为data的打印结果,返回值为"保存成功"
        # ImmutableMultiDict([('pic', <FileStorage: '2018-08-07 16-54-02屏幕截图.png' ('image/png')>)])
        # <FileStorage: '2018-08-07 16-54-02屏幕截图.png' ('image/png')>
        if request.filr
            pic = request.files.get('pic')
            print(pic)
            pic.save('./12.png')
            return '保存成功'
        return "查看控制台"

5、状态保持

  • 由于HTTP是无状态的用户发送一次请求时浏览器和服务器不知道用户之前有什么操作每次请求都是独立的一次的新请求,
  • Cookie:指某些网站为了辨别用户身份,进行会话追踪而存储在用户本地的数据
    • Cookie由服务器端生成随响应发送给客户端,客户端以key/value的形式保存在客户端,并在下次请求同一网站时发送该cookie给服务器(前提是浏览器启用了cookie)
    • 因为Cookie是纯文本信息所以建议不要存储敏感信息
    • Cookie基于域名安全和浏览器的同源策略所以使用同一浏览器同时访问不同网站时任意一个网站访问不到到其他网站的cookie。但是由于Cookie是自动发送的所以会存在SCRF攻击风险
  • 设置cookie:
  • from flask imoprt Flask,make_response
    
    @app.route('/cookie')
    def set_cookie():
        # 将'this is to set cookie'设置到响应中去
        resp = make_response('this is to set cookie')
        # 在响应中加入cookie,key为'username' value为'li',
        # max_age 设置cookie的过期时间为3600秒,默认为31天
        resp.set_cookie('username', 'li',max_age=3600)
        # 返回该响应
        return resp
  • 获取cookie
    @app.route('/request')
    def resp_coookie():
        # 获得cookie中的username的值
        resp = request.cookirs.get('username')
        print (resp)
        return resp
  • 删除cookie
  • @app.route('/delcookie')
    def del_cookie():
        # 设置响应为'删除 cookie'
        resp = make_response('删除 cookie')
        # 加入删除客户端的key为"uesrname"的cookie
        # 删除方法是设置过期时间于保存时间一致
        resp.delete_cookie('uesrname')
        return resp
  • session:另一种保存用户状态信息的方法

    • 基于cookie的存在于服务端的用于存储用户状态信息以及不方便使用cookie保存在客户端的用户敏感信息

    • 使用session时服务器会发送自动发送一个值唯一的cookie到客户端浏览器用于用户再次发起时从服务端获取用户的状态信息

  • 设置session(记得设置secret_key: app.secret_key = '任意' )
  • @app.route('/login')
    def login():
        # 更改有效期为30天,并且可以设置有效期
        session.permanent = True
        # 设置session
        session['username'] = "laowang"
        session['user_id'] = "18"
        return "登录成功"
    
    
  • 获取session
  • 
    @app.route('/userinfo')
    def user_info():
        # 获取session
        username = session.get("username")
        user_id = session.get("user_id")
        # 打印
        print("username=%s" % username)
        print("user_id=%s" % user_id)
        return '用户信息'

    6、上下文

  • 请求上下文(request context)
    • 用于获取请求的相关数据。请求上下文对象有request、session
    • request:记录HTTP请求的内容,针对http请求。如:user = request.args.get('user'),获取get请求中的
    • session:记录会话中的信息,针对的是用户信息。如:session['name'] = user.id,可以记录用户信息。还可以通过session.get('name')获取用户信息。
  • 应用上下文(application context)
    • current_app:用于存储应用程序中的变量,如:可以通过current_app.name打印当前app的名称,也可以在current_app中存储一些变量
    • g变量:flask程序全局的一个临时变量,在一次请求中充当中间媒介,可以在不同的视图函数中传递一些数据,g保存的是当前请求的全局变量。不同的请求g不同,通过不同的thread id区分。
  • 两个上下文的区别
    • 请求上下文:保存了客户端和服务器交互的数据
    • 应用上下文:flask 应用程序运行过程中,保存的一些配置信息,比如程序名、数据库连接、应用信息等

错误之处欢迎指出

猜你喜欢

转载自blog.csdn.net/jlb1024/article/details/81485260
今日推荐