基于Tornado自定制仿Django的Session以及Form组件

Posted Mitsuis

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于Tornado自定制仿Django的Session以及Form组件相关的知识,希望对你有一定的参考价值。

一、session

1.Session本质是保存在服务器端的数据,可以看作是键值对。

 

用户第一次打开网站页面
- 生成一段随机字符串,作为value发给客户端浏览器,客户端带着字符串获取对应的session
- 在session中保存,随机字符串作为key,value={‘user‘:‘Mitsui‘,‘pwd‘:123....}

2.session模块代码:
import time
import hashlib
import settings

def get_random_str():
    """
    获取作为session key的随机字符串
    :return:
    """
    md5 = hashlib.md5()
    md5.update(str(time.time()).encode(‘utf-8‘))
    return md5.hexdigest()

class RedisSession(object):
    def __init__(self,handler):
        """
        基于Redis在服务端存储session
        :param handler:
        """
        self.handler = handler
        self.session_id = settings.SESSION_ID
        self.expires = settings.EXPIRERS
        self.initial()

    @property
    def conn(self):
        import redis
        conn = redis.Redis(host=‘192.168.xx.xx‘,port=6379)
        return conn

    def initial(self):
        client_random_str = self.handler.get_cookie(self.session_id)

        if client_random_str and self.conn.exists(client_random_str):
            self.random_str = client_random_str
        else:
            self.random_str = get_random_str()

        expires = time.time() + self.expires
        self.handler.set_cookie(self.session_id,self.random_str,expires=expires)
        #除了对浏览器cookies设置超时时间,也需要对redis数据设置超时时间,可以定时清除数据节省空间
        self.conn.expire(self.random_str,self.expires)

    def __getitem__(self, item):
        """
        取session,item为key,如self.session[‘user‘]
        :param item:
        :return:
        """
        import json
        #由于Python数据类型直接存入redis后受到转换,因此在存储时会先dumps,相应的取值时会先loads。
        data_str = self.conn.hget(self.random_str,item)
        if data_str:
            return json.loads(data_str)
        else:
            return None

    def __setitem__(self, key, value):
        """
        设置session
        :param key:
        :param value:
        :return:
        """
        import json
        self.conn.hset(self.random_str,key,json.dumps(value))

    def __delitem__(self, key):
        """
        删除session
        :param key:
        :return:
        """
        self.conn.hdel(self.random_str)

class CacheSession(object):

    container = {}

    def __init__(self,handler):
        """
        普通的内存存取session
        :param handler: 视图函数传进的self,可以使用get_cookie等方法
        """
        self.handler = handler
        self.session_id = settings.SESSION_ID   #存储在浏览器的cookies的key
        self.expires = settings.EXPIRERS        #超时时间
        self.initial()

    def initial(self):
        """

        :return:
        """
        client_random_str = self.handler.get_cookie(self.session_id)
        if client_random_str and client_random_str in self.container:
            #如果session中已经有值,赋原值刷新超时时间
            self.random_str = client_random_str
        else:
            #没有则获取随机字符串 作为session的key存储在内存中container,并设置超时时间,
            self.random_str = get_random_str()
            self.container[self.random_str] = {}
        expires = time.time() + self.expires
        self.handler.set_cookie(self.session_id,self.random_str,expires=expires)

    def __getitem__(self, item):
        """
        获取session
        :param item:key,  session[‘user‘]
        :return:
        """
        return self.container[self.random_str].get(item)

    def __setitem__(self, key, value):
        """
        设置session
        :param key:  session[‘user‘]
        :param value:    =user
        :return:
        """
        self.container[self.random_str][key] = value

    def __delitem__(self, key):
        """
        删除session   del self.session时触发
        :param key:
        :return:
        """
        if key in self.container[self.random_str]:
            del self.container[self.random_str][key]



class SessionFactory(object):
    """
    读取配置文件,根据配置文件返回定制的session类
    """
    @staticmethod
    def get_session():
        import settings
        import importlib
        engine = settings.SESSION_ENGINE
        module_path,cls_name = engine.rsplit(‘.‘,maxsplit=1)
        md = importlib.import_module(module_path)
        cls = getattr(md,cls_name)
        return cls

 

3.基于Tornado的使用:

import tornado.ioloop
import tornado.web
from tornado.web import RequestHandler
from session_code import SessionFactory

class SessionHandler(object):
    def initialize(self,*args,**kwargs):
        cls = SessionFactory.get_session()
        # cls是CacheSession对象,RedisSession对象
        #执行cls的init方法
        self.session = cls(self)


class LoginHandler(SessionHandler,RequestHandler):
    """
    init方法执行之后,执行get 跟post方法之前,会先执行initialize方法,
    这里用多继承的方法继承自SessionHandler,执行initialize方法,获取
    CacheSession或者RedisSession对象的session方法
    """

    def get(self, *args, **kwargs):
        self.render("login.html")
    def post(self, *args, **kwargs):
        user = self.get_argument(‘user‘)
        pwd = self.get_argument(‘pwd‘)
        if user == "Mitsui" and pwd == ‘123‘:
            self.session[‘user‘] = user
            self.redirect(‘/index‘)
        else:
            self.render(‘login.html‘)


class IndexHandler(SessionHandler,RequestHandler):

    def get(self, *args, **kwargs):
        user = self.session[‘user‘]
        if user:
            self.write(‘欢迎登录!‘)
        else:
            self.redirect(‘/login‘)


sett = {
    ‘template_path‘:‘views‘,
    #XSRF
    ‘xsrf_cookies‘:True,
}

application = tornado.web.Application([
    (r"/login",LoginHandler),
    (r"/index",IndexHandler),
],**sett)

if __name__ == ‘__main__‘:
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

  

配置文件settings:

#所选的session处理类
SESSION_ENGINE = "session_code.CacheSession"
#客户端cookie中保存的key
SESSION_ID = "__session__id__"
#超时时间
EXPIRERS = 300

  

 

 



 

以上是关于基于Tornado自定制仿Django的Session以及Form组件的主要内容,如果未能解决你的问题,请参考以下文章

新闻网站电脑版带手机版源码,仿东方头条,今日头条,搜狐自媒体网站帝国cms定制

Django自定制插件之随机验证码

自定义模板方法(类似django中的simple_tag) | Tornado

看用Tornado如何自定义实现表单验证

tornado 模板引擎

11.Django(自定制过滤器自定制标签)