第四篇 与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如何实现的?

 

 

三.

posted @ 2018-08-15 13:37  mamingchen  阅读(310)  评论(0编辑  收藏  举报