• 第四篇 与Flask相关的插件(flask-session、wtforms)


    公司中使用SQL的种方式:

    1. 写Django:ORM(关系对象映射), 

    2. 写Flask和其他:有两种方式:

      (1) 原生SQL:使用原生SQL有两种选择:

        A. pymysql (python2 和 python3均支持)

        B. MySQLDB (仅python2支持)

      (2) SQLAchemy (也是一种ORM框架,与Django的ORM类似)

      ORM的内部又会调用pymysql或者MySQLdb,所以其本质还是要会pymysql 和 MySQLdb

    一. Flask session

    1. Flask中session处理机制

    (1)请求刚到来:获取随机字符串,检测字符串是否存在,若存在则去“数据库”中获取原来的个人数据;如果不存在,就在内存里创建一个空容器(对象)供用户使用,该对象包括两项内容:随机字符串,{放置数据的容器}

    (2)接下来走视图函数,或者业务处理(如登录),应该要读取session了:操作内存中的对象(随机字符串,{放置数据的容器})

    (3)操作完毕即响应终止了,该给什么返回就给了,即响应:对内存中的对象(随机字符串,{放置数据的容器})进行两步操作:

      1) 将将数据保存到数据库

      2) 把随机字符串写在用户cookie中

       # 1. obj = 创建SecureCookieSessionInterface()
       # 2. obj = open_session(self.request) = SecureCookieSession()
       # self.session = SecureCookieSession()对象。 
       # self.session = self.app.open_session(self.request)

    对于Flask的 内置session,是将session保存在加密cookie中实现

    2.如何自定义一个session

    请求刚到来:
        # 创建特殊字典,并添加到Local中。
        # 调用关系:
        #    self.session_interface.open_session(self, request)
        #     由于默认app中的session_interface=SecureCookieSessionInterface()
        #        SecureCookieSessionInterface().open_session(self, request)
        #     由于默认app中的session_interface=MySessionInterFace()
        #        MySessionInterFace().open_session(self, request)
        self.session = self.app.open_session(self.request)
    
    调用:
        session -> LocalProxy -> 偏函数 -> LocalStack -> Local
    
    请求终止:
        #     由于默认app中的session_interface=SecureCookieSessionInterface()
        #        SecureCookieSessionInterface().save_session(self, app, session, response)
        #     由于默认app中的session_interface=MySessionInterFace()
        #        MySessionInterFace().save_session(self, app, session, response)
    from flask import Flask, session, redirect, url_for, escape, request
     
    app = Flask(__name__)
     
    @app.route('/')
    def index():
        if 'username' in session:
            return 'Logged in as %s' % escape(session['username'])
        return 'You are not logged in'
     
    @app.route('/login', methods=['GET', 'POST'])
    def login():
        if request.method == 'POST':
            session['username'] = request.form['username']
            return redirect(url_for('index'))
        return '''
            <form action="" method="post">
                <p><input type=text name=username>
                <p><input type=submit value=Login>
            </form>
        '''
     
    @app.route('/logout')
    def logout():
        # remove the username from the session if it's there
        session.pop('username', None)
        return redirect(url_for('index'))
     
    # set the secret key.  keep this really secret:
    app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
    
    基本使用
    基本使用
    pip3 install Flask-Session
            
            run.py
                from flask import Flask
                from flask import session
                from pro_flask.utils.session import MySessionInterface
                app = Flask(__name__)
    
                app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
                app.session_interface = MySessionInterface()
    
                @app.route('/login.html', methods=['GET', "POST"])
                def login():
                    print(session)
                    session['user1'] = 'alex'
                    session['user2'] = 'alex'
                    del session['user2']
    
                    return "内容"
    
                if __name__ == '__main__':
                    app.run()
    
            session.py
                #!/usr/bin/env python
                # -*- coding:utf-8 -*-
                import uuid
                import json
                from flask.sessions import SessionInterface
                from flask.sessions import SessionMixin
                from itsdangerous import Signer, BadSignature, want_bytes
    
    
                class MySession(dict, SessionMixin):
                    def __init__(self, initial=None, sid=None):
                        self.sid = sid
                        self.initial = initial
                        super(MySession, self).__init__(initial or ())
    
    
                    def __setitem__(self, key, value):
                        super(MySession, self).__setitem__(key, value)
    
                    def __getitem__(self, item):
                        return super(MySession, self).__getitem__(item)
    
                    def __delitem__(self, key):
                        super(MySession, self).__delitem__(key)
    
    
    
                class MySessionInterface(SessionInterface):
                    session_class = MySession
                    container = {}
    
                    def __init__(self):
                        import redis
                        self.redis = redis.Redis()
    
                    def _generate_sid(self):
                        return str(uuid.uuid4())
    
                    def _get_signer(self, app):
                        if not app.secret_key:
                            return None
                        return Signer(app.secret_key, salt='flask-session',
                                      key_derivation='hmac')
    
                    def open_session(self, app, request):
                        """
                        程序刚启动时执行,需要返回一个session对象
                        """
                        sid = request.cookies.get(app.session_cookie_name)
                        if not sid:
                            sid = self._generate_sid()
                            return self.session_class(sid=sid)
    
                        signer = self._get_signer(app)
                        try:
                            sid_as_bytes = signer.unsign(sid)
                            sid = sid_as_bytes.decode()
                        except BadSignature:
                            sid = self._generate_sid()
                            return self.session_class(sid=sid)
    
                        # session保存在redis中
                        # val = self.redis.get(sid)
                        # session保存在内存中
                        val = self.container.get(sid)
    
                        if val is not None:
                            try:
                                data = json.loads(val)
                                return self.session_class(data, sid=sid)
                            except:
                                return self.session_class(sid=sid)
                        return self.session_class(sid=sid)
    
                    def save_session(self, app, session, response):
                        """
                        程序结束前执行,可以保存session中所有的值
                        如:
                            保存到resit
                            写入到用户cookie
                        """
                        domain = self.get_cookie_domain(app)
                        path = self.get_cookie_path(app)
                        httponly = self.get_cookie_httponly(app)
                        secure = self.get_cookie_secure(app)
                        expires = self.get_expiration_time(app, session)
    
                        val = json.dumps(dict(session))
    
                        # session保存在redis中
                        # self.redis.setex(name=session.sid, value=val, time=app.permanent_session_lifetime)
                        # session保存在内存中
                        self.container.setdefault(session.sid, val)
    
                        session_id = self._get_signer(app).sign(want_bytes(session.sid))
    
                        response.set_cookie(app.session_cookie_name, session_id,
                                            expires=expires, httponly=httponly,
                                            domain=domain, path=path, secure=secure)
    
    自定义Session
    自定义session
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    """
    pip3 install redis
    pip3 install flask-session
    
    """
    
    
    from flask import Flask, session, redirect
    from flask.ext.session import Session
    
    
    app = Flask(__name__)
    app.debug = True
    app.secret_key = 'asdfasdfasd'
    
    
    app.config['SESSION_TYPE'] = 'redis'
    from redis import Redis
    app.config['SESSION_REDIS'] = Redis(host='192.168.0.94',port='6379')
    Session(app)
    
    
    @app.route('/login')
    def login():
        session['username'] = 'alex'
        return redirect('/index')
    
    
    @app.route('/index')
    def index():
        name = session['username']
        return name
    
    
    if __name__ == '__main__':
        app.run()
    
    第三方session
    第三方session

    3.flask-session组件的使用和原理

    二.WTForms

    1. 回顾:

    metaclass:说明当前类是由哪个基类创建的

    class MyType(type):
        def __init__(self,*args,**kwargs):
            print('init')
            super(MyType,self).__init__(*args,**kwargs)
    
        def __call__(self, *args, **kwargs):
            print('call本质:调用类的__new__,再调用类的__init__')
            return super(MyType,self).__call__( *args, **kwargs)
    
    # 创建Foo类的时候,调用MyType的__init__
    class Foo(metaclass=MyType):
        print('foo')
    # 创建Bar类的时候,调用MyType的__init__
    class Bar(Foo):
        print("--")
    
    # 调用Bar的时候才执行__call__
    obj = Bar()
    metaclass
    class MyType(type):
        def __init__(self, *args, **kwargs):
            super(MyType, self).__init__(*args, **kwargs)
    
        def __call__(cls, *args, **kwargs):
            print('xxxx')
            return super(MyType, cls).__call__(*args, **kwargs)
    
    
    # Base = MyType('Base', (object,), {})
    
    # MyType('Base', (object,), {}) 是由MyType创建; 相当于 metaclass=MyType
    # 1. type可以创建类metaclass=type;MyType也可以创建类metaclass=MyType
    # 2. Base = MyType('Base', (object,), {}) 等价于
    
    # metaclass的第一种写法
    # class Base(metaclass=MyType):
    #     pass
    # class Foo(Base):
    #     pass
    
    # metaclass的第二种写法
    class Foo(MyType('Base', (object,), {})):
        pass
    obj = Foo()
    MyType('Base', (object,), {})
    class MyType(type):
        def __init__(self, *args, **kwargs):
            super(MyType,self).__init__(*args, **kwargs)
    
        def __call__(self, *args, **kwargs):
            return super(MyType,self).__call__(*args, **kwargs)
    
    # 函数,函数的返回值
    def with_metaclass(base):
        return MyType('xx',(base,),{})   # MyType('xx',(base,),{}) 也是创建了一个类,只不过被封装到了函数里去了
    
    class Foo(with_metaclass(object)):
        pass
    把创建类的代码封装在函数里

    2.如果简单使用WTForms

    (1) 安装:pip install wtforms

    3.WTForms如何实现的?

    三.

  • 相关阅读:
    slf4j的使用
    hashMap
    HBase
    HBase应用快速开发
    初学MongoDB 遇到提示由于目标计算机积极拒绝,无法连接
    Flask学习中运行“helloworld”出现UnicodeDecodeError: 'utf-8' codec can't decode问题
    doGet或doPost方法没有调用的一个原因
    markdown测试
    tomcat集成到IDEA与部署项目
    tomcat部署项目的方式
  • 原文地址:https://www.cnblogs.com/victorm/p/9467395.html
Copyright © 2020-2023  润新知