zoukankan      html  css  js  c++  java
  • Flask的基础二

    一、session

    除请求对象之外,还有一个 session 对象。它允许你在不同请求间存储特定用户的信息。它是在 Cookies 的基础上实现的,并且对 Cookies 进行密钥签名要使用会话,你需要设置一个密钥。

    • 设置:session['username'] = 'xxx'
    • 取值:session.get['username']
    • 删除:session.pop('username', None)
    from flask import Flask
    from flask import render_template
    from flask import session
    from flask import request
    from flask import redirect
    
    app = Flask(__name__)
    
    app.config.from_mapping({"SECRET_KEY":"value"})
    
    @app.route("/login",methods=["GET","POST"])
    def login():
        if request.method == "POST":
            username = request.form.get("username")
            password = request.form.get("password")
            if username == "xiaoming" and password == "123":
                # 登陆成功后设置session
                session["userinfo"] = {"name":username}
                return redirect("/")
        return render_template("login.html")
    
    @app.route("/")
    def index():
        # 获取session
        print(session["userinfo"])
        return "首页"
    
    if __name__ == '__main__':
        app.run()

     

    二、flash 闪现

    闪现的作用:flash设置值只能取一次

    闪现的原理:利用session设置值,通过pop的方法删除并返回值,取值的时候调用session.pop()的方法将值放到flashes中,请求还在取值都从flashes中获取

    '''
    存一次只能取一次值,用session模拟闪现
    '''
    from flask import Flask,session
    
    app = Flask(__name__)
    app.secret_key = "key"      # 设置session需要设置secret_key
    
    @app.route("/set")
    def set():
        session['name'] = "xiaoming"
        return "Set name"
    
    @app.route("/get")
    def get():
        # 删除session的键值对并取值
        name = session.pop("name","")
        print(name)
        return name
    
    
    if __name__ == '__main__':
        app.run()
    session模拟flash
    # 设置值
    flash(message, category='message')
    
    # 获取值
    get_flashed_messages(with_categories=False, category_filter=[])
    from flask import Flask,flash,get_flashed_messages
    
    app = Flask(__name__)
    app.secret_key = "key"
    
    @app.route("/set")
    def set():
        flash("xiaoming")   # 设置值
        flash(18,"age")     # 参数:message,分类
        return "flash设置值"
    
    @app.route("/get")
    def get():
        # 取值
        name = get_flashed_messages()  
        
        # 按分类取值category_filter=[]
        age = get_flashed_messages(category_filter=["age"])
        print(name)
        print(age)
        return "GET"
    
    if __name__ == '__main__':
        app.run()

     

    三、中间件

    app.run()        #程序的入口
    
    run_simple(host, port, self, **options)        # run的本质是调用run_simple
    # host == ip
    # port == 端口
    # self == app
    
    # 执行了self() 相当于执行app(),调用app的__call__方法
    # app.__call__
    
    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)
    
    # 相当于执行 app.wsgi_app(environ, start_response)
    app.run的源码流程
    '''
    中间件的实现
    '''
    
    from flask import Flask
    
    app = Flask(__name__)
    
    class Middleware(object):
        def __init__(self,old_wsgi_app):
            # 原来的wsgi_app
            self.wsgi_app= old_wsgi_app
    
        def __call__(self, *args, **kwargs):
            print("项目启动之前")
            # wsgi_app是原来的wsgi_app
            ret = self.wsgi_app(*args, **kwargs)
            print("项目启动之后")
            return ret
    
    
    
    if __name__ == '__main__':
        # 将旧的app.wsgi_app赋值给新的app.wsgi_app
        app.wsgi_app = Middleware(app.wsgi_app)
        app.run()
    
    '''
     * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
    项目启动之前
    127.0.0.1 - - [28/Dec/2018 16:43:27] "GET / HTTP/1.1" 404 -
    项目启动之后
    '''

     

    四、特殊的装饰器

    @app.before_first_request # 第一次请求
    @app.before_request # 每一次请求
    @app.after_request # 每一次响应

    注意:before_request有返回值,不走视图函数,直接走after_request
    @app.template_global()
    @app.template_filter()
    @app.errorhandler(404)

    '''
    自定义装饰器实现登陆认证
    '''
    
    from flask import Flask
    from functools import wraps
    from flask import url_for
    from flask import session
    from flask import render_template
    from flask import request,redirect
    
    
    app = Flask(__name__)
    app.secret_key = "key"
    
    # 自定义装饰器
    def Auth_decorator(func):
        @wraps(func)
        def inner(*args,**kwargs):
            # 访问是否携带认证,否则跳转都登陆页面
            if not session.get("user",""):
                return redirect("login")
            ret = func(*args,**kwargs)
            return ret
        return inner
    
    
    
    # 登陆
    @app.route("/login",endpoint="login",methods=["GET","POST"])
    def login():
        if request.method == "POST":
            username = request.form.get("username")
            password = request.form.get("password")
            if username == "xiaoming" and password == "123":
                # 登陆成功后设置session
                session["user"] = username
                return redirect(url_for("myhome"))
        return render_template("login.html")
    
    # 登陆成功后跳转的页面
    @app.route("/home",endpoint="myhome")
    @Auth_decorator
    def home():
        return "登陆成功的HOME页面"
    
    if __name__ == '__main__':
        app.run()
    自定义登陆认证的装饰器
    # 模板的全局装饰器
    @app.template_global()
    def mysum(n1,n2):
        return n1+n2
    
    # HTML
    {{ mysum(10,5) }}
    @app.template_global()
    # 模板的筛选器
    @app.template_filter()
    def myfilter(data):
        return data[::2]
    
    # HTML
    {{ "today hello" | myfilter() }}
    模板的筛选器
    # 路径不存在跳转到指定页面的装饰器
    @app.errorhandler(404)
    def error_page(error):
        return render_template("error404.html")
    路径不存在返回页面

     

    五、路由的实现原理

    不能有多个endpoint指向同一个视图函数,内部是{'endpoint':"view_func"}

    app.route()
    # 执行route函数
    route(self, rule, **options)    
    # self == app
    # rule == 路由
    
    # 返回decorator函数
    return decorator
    
    # decorator函数,传入视图函数
    def decorator(f):
        endpoint = options.pop('endpoint', None)
        self.add_url_rule(rule, endpoint, f, **options)
        return f
    
    # 调用add_url_rule(路由,endpoint,视图函数)
    def add_url_rule(self, rule, endpoint=None, view_func=None,provide_automatic_options=None, **options):
        # endpoint不能有多个视图函数,否则抛出异常
        if view_func is not None:
            old_func = self.view_functions.get(endpoint)
            if old_func is not None and old_func != view_func:
                raise AssertionError('View function mapping is overwriting an '
                                     'existing endpoint function: %s' % endpoint)
            self.view_functions[endpoint] = view_func
    route源码流程
    '''
    根据路由原理创建Flask项目
    '''
    from flask import Flask
    
    # 实例化Flask对象
    app = Flask(__name__)
    
    def index():
        return "这是首页"
    
    # 调用app.route的核心方法,实行app.route
    app.add_url_rule("/",view_func=index)
    
    if __name__ == '__main__':
        app.run()

    六、CBV编程

    1.类继承views.MethodView
    2.装饰器修饰的列表 decorators = []
    3.指定路由和类 app.add_url_rule

    from flask import Flask
    from flask import views
    
    app = Flask(__name__)
    
    class MyView(views.MethodView):
        # decorators = []               # 存放装饰器的列表
        # methods = ["GET","POST"]      # 请求方式列表,用于限制的
    
        def get(self):
            return "GET"
    
        def post(self):
            return "POST"
    
    app.add_url_rule("/",view_func=MyView.as_view(name="index"))
    
    if __name__ == '__main__':
        app.run()

    七、自定义路由正则匹配

    from flask import Flask,url_for
    from werkzeug.routing import BaseConverter
    
    app = Flask(__name__)
    
    
    class RegexConverter(BaseConverter):
        '''
        自定义URL匹配正则表达式
        '''
    
        def __init__(self,map,regex):
            super(RegexConverter,self).__init__(map)
            self.regex = regex
    
        def to_python(self, value):
            '''
            路由匹配时,匹配成功后传递给视图函数中参数的值
            :param value:
            :return:
            '''
            return value
    
        def to_url(self, value):
            '''
            使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
            :param value:
            :return:
            '''
            val = super(RegexConverter,self).to_url(value)
            return val
    
    # 添加到flask中
    app.url_map.converters['regex'] = RegexConverter
    
    @app.route("/index/<regex('d+'):id>")
    def index(id):
        print(url_for('index',id='123'))
        print(type(id))
        return "{}".format(id)
    
    if __name__ == '__main__':
        app.run()
  • 相关阅读:
    Sql server 经典常用函数
    Sql Server 时间格式化
    eval解析JSON中的注意点
    SQL Server 数据库try catch 存储过程
    SQL 添加索引
    sql中的begin catch 。。。end catch 的用法
    常用正则表达式
    css3实现背景渐变
    CacheHelper
    星座运势(等)接口控制器
  • 原文地址:https://www.cnblogs.com/st-st/p/10186826.html
Copyright © 2011-2022 走看看