1 2 3 4

【python之路44】tornado的用法 (二)

参考:https://www.cnblogs.com/sunshuhai/articles/6253815.html

 

一、代码目录构建

代码目录设置如下图:

 

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.web


class LogInHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("LogIn")

class LogOutHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("LogOut")

class RegistHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Regist")
account.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.web


class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Index")
home.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.ioloop
import tornado.web
from controllers import account
from controllers import home


settings = {
    'template_path':'views', #配置模板文件路径
    'static_path':'statics', #配置静态文件路径
}
#路由映射
application = tornado.web.Application([
    (r"/login", account.LogInHandler),
    (r"/logout", account.LogOutHandler),
    (r"/regist", account.RegistHandler),
    (r"/index", home.IndexHandler)
],**settings)   #**settings是让配置生效

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

 二、基于正则的动态路由

(r"/index/(\d+)", home.IndexHandler)
class IndexHandler(tornado.web.RequestHandler):
def get(self,num):
print(num)
self.write("Index")

http://127.0.0.1:8888/index/11,用这个url访问时会打印输出:11

(r"/index/(\d+)/(\d*)", home.IndexHandler)
class IndexHandler(tornado.web.RequestHandler):
def get(self,num,page):
print(num,page)
self.write("Index")

http://127.0.0.1:8888/index/11/22,用这个url访问时会打印输出:11,22

(r"/index/(?P<page>\d+)/(?P<num>\d*)", home.IndexHandler)  #?P<page>匹配到的第一个分组命名为page
class IndexHandler(tornado.web.RequestHandler):
def get(self,num,page):
print(num,page)
self.write("Index")

http://127.0.0.1:8888/index/11/22,用这个url访问时会打印输出:22,11

 (三)XSS跨站脚本攻击

如下面这个html

<h1>aaaaa<h1>
<script>alert(123)</script>

这个html一旦被访问就会运行script代码,弹窗显示123

那么在一些网站中的文本框中可以输入script代码,一旦网站没有对代码做相应的处理,就会运行

tornado是做了处理的,文本框中输入代码是作为文本的,但也可以原始状态展示,这样就会运行这段代码,例如:

<td>{% raw item["email"] %}</td>

这样一旦添加数据后,代码会被执行,会直接弹窗显示123

四、分页 

其中home.py中的class Page类可以直接当做插件用,可以使用在其他的web框架中

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.web


class LogInHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("LogIn")

class LogOutHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("LogOut")

class RegistHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Regist")
account.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>分页</title>
    <style>
        .page a{
            display: inline-block;
            padding: 5px;
            margin:3px;
            background-color: darkseagreen;
        }
        .page a.ActivePage{
            background-color: brown;
            color: aliceblue;
        }
    </style>
</head>
<body>
    <form method="post" action="/index/">
        用户名:<input type="text" name="username">
        邮箱:<input type="text" name="email">
        <input type="submit" value="提交">
    </form>

    <table>
        <thead>
            <tr>
                <th>用户名</th>
                <th>邮箱</th>
            </tr>
        </thead>
        <tbody>
            {% for item in  list_info %}
                <tr>
                    <td>{{item["username"]}}</td>
                    <!--<td>{{item["email"]}}</td>-->
                    <td>{% raw item["email"] %}</td>
                </tr>
            {% end %}
        </tbody>
    </table>


<div class="page">
    {% raw html_a %}
</div>

</body>
</html>
index.html
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.ioloop
import tornado.web
from controllers import account
from controllers import home


settings = {
    'template_path':'views', #配置模板文件路径
    'static_path':'statics', #配置静态文件路径
}
#路由映射
application = tornado.web.Application([
    (r"/login", account.LogInHandler),
    (r"/logout", account.LogOutHandler),
    (r"/regist", account.RegistHandler),
    (r"/index/(?P<page>\d*)", home.IndexHandler)
],**settings)   #**settings是让配置生效

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()
start.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.web
import math
LIST_INFO = []
for i in range(999):
    LIST_INFO.append({"username":"sunshuhai" + str(i),"email": str(i) + "123.qq.com"})

class Page:
    #分页的内容-列表,当前页码,每页的数据条数,基础url
    def __init__(self,list_content,crrent_page,num_of_page,base_url):
        try:
            crrent_page = int(crrent_page)
        except:
            crrent_page = 1
        if crrent_page<1:
            crrent_page = 1
        quotient,remainder =divmod(len(list_content),num_of_page)
        if remainder>0:
            all_page=quotient+1
        else:
            all_page =quotient
        self.all_page = all_page
        self.crrent_page = crrent_page
        self.num_of_page = num_of_page
        self.base_url = base_url
    @property
    def start(self):
        return (self.crrent_page - 1) * self.num_of_page
    @property
    def end(self):
        return self.crrent_page * self.num_of_page
    def crrent_page_content(self):
        pass
    def show_page_html(self):
        list_html=[]
        if self.all_page <= 11:
            start_page = 1
            end_page = self.crrent_page
        else:
            if self.crrent_page<=6:
                start_page = 1
                end_page = 11
            else:
                if self.crrent_page+5 >self.all_page:
                    start_page = self.all_page-10
                    end_page = self.all_page
                else:
                    start_page = self.crrent_page - 5
                    end_page = self.crrent_page + 5
        befor = '<a href="%s1">首页</a>' % (self.base_url)
        list_html.append(befor)
        if self.crrent_page-1>=1:
            next_page = '<a href="%s%s">上一页</a>' % (self.base_url,self.crrent_page-1)
        else:
            next_page = '<a href="javascript:void(0)">上一页</a>'
        list_html.append(next_page)
        for  p in range(start_page,end_page+1):
            if p==self.crrent_page:
                list_html.append('<a class="ActivePage" href="%s%s">%s</a>' % (self.base_url,p, p))
            else:
                list_html.append('<a href="%s%s">%s</a>' %(self.base_url,p,p))
        if self.crrent_page >= self.all_page:
            previous_page = '<a href="javascript:void(0)">下一页</a>'
        else:
            previous_page = '<a href="%s%s">下一页</a>' % (self.base_url,self.crrent_page+1)
        list_html.append(previous_page)
        after ='<a href="%s%s">尾页</a>' %(self.base_url,self.all_page)
        list_html.append(after)
        jump = """<input type="text"><a onclick="Jump('%s',this);">GO</a>""" %(self.base_url)
        javasc = """
        <script>
            function Jump(baseUrl,ths) {
                var val = ths.previousElementSibling.value;
                if(val.trim().length>0){
                    location.href=baseUrl + val;
                }
            }
        </script>
        """
        list_html.append(jump)
        list_html.append(javasc)

        html_str = ''.join(list_html)
        return html_str



class IndexHandler(tornado.web.RequestHandler):
    def get(self,page):
        #每5条数据分一页[0:5] [5:10] [10:15]
        page = Page(LIST_INFO,page,20,"/index/")
        list_page = LIST_INFO[page.start:page.end]
        html_str  =page.show_page_html()
        self.render("index.html",list_info = list_page,html_a = html_str)
    def post(self, *args, **kwargs):
        user = self.get_argument("username")
        email = self.get_argument("email")
        temp_dict = {"username":user,"email":email}
        LIST_INFO.append(temp_dict)
        p = math.ceil(len(LIST_INFO)/5)
        self.redirect("/index/%s" %p)
home.py

 五、路由系统之二级域名支持

1)首先配置host文件模拟域名访问

127.0.0.1 localhost
127.0.0.1 ssh.com
127.0.0.1 buy.ssh.com

2)配置路由系统

#路由映射
application = tornado.web.Application([
(r"/login", account.LogInHandler),
(r"/logout", account.LogOutHandler),
(r"/regist", account.RegistHandler),
(r"/index/(?P<page>\d*)", home.IndexHandler)
],**settings) #**settings是让配置生效
application.add_handlers('buy.ssh.com$',[
(r"/index/(?P<page>\d*)",buy.IndexHandler)
])

buy.py中的IndexHandler为:
import tornado.web
class IndexHandler(tornado.web.RequestHandler):
def get(self,page):
self.write("buy.Index")

3)用域名访问:http://buy.ssh.com:8888/index/1

结果显示:

六、模板引擎的补充用法(继承:extends,导入:include) 

1)extends 继承

母版的html中可以使用占位符

<div calss="pg-content">
{% block body %}{% end %}
</div>

如果继承上面母版中有占位符的html,只需要替换占位符的位置就可以

{% extends '../master/layout.html' %}
{% block boy %}
<h1>Index</h1>
{% end %}

继承母版的优点:公共样式都可以放在母版中,个别样式继承母版后进行替换

 2)include 导入

一些共用的小的组件,可以设置为共用,html如果想用只需要导入即可

下面是form.html中的共用代码:

<form action="/">
<input type="text">
<input type="submit">
</form>

使用时只需要导入即可,实际就相当于在导入的位置写了form标签的代码。

{% block body %}
<h1>Index</h1>
{% include '../include/form.html' %}
{% end %}

 3)实例如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.web
class IndexHandler(tornado.web.RequestHandler):
    def get(self,*args,**kwargs):
        self.render('extend/index.html',info_list=['111','222','333'])

class FuckOffHandler(tornado.web.RequestHandler):
    def get(self,*args,**kwargs):
        self.render('extend/fuck.html')
extend.py
{% extends '../master/layout.html' %}
{% block body %}
    <h1>fuckoff</h1>
{% end %}

{% block js %}
    <script>
        cosole.log('fuckoff')
    </script>
{% end %}
fuck.html
{% extends '../master/layout.html' %}
{% block css %}
    <style>
        div{
            border:1px solid red;
        }
    </style>
{% end %}
{% block body %}
    <h1>Index</h1>
    {% include '../include/form.html' %}
{% end %}

{% block js %}
    <script>
        cosole.log('index')
    </script>
{% end %}
index.html
<form action="/">
    <input type="text">
    <input type="submit">
</form>
<ul>
    {% for item in info_list %}
        <li>{{item}}</li>
    {% end %}
</ul>
form.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .pg-header{
            height: 48px;
            background-color: black;
        }
        .pg-footer{
            height: 100px;
            background-color: #dddddd;
        }
    </style>
    <!--block块上面是共用样式,下面是具体每个页面的自定制样式-->
    {% block css %}{% end %}
</head>
<body>
    <div class="pg-header">

    </div>
    <div calss="pg-content">
        {% block body %}{% end %}
    </div>
    <div class="pg-footer">
        我是页面底部
    </div>
    <script src="xxxxj"></script>
    <!--block块上面是共用js,下面是具体每个页面的自定制js-->
    {% block js %}{% end %}
</body>
</html>
layout.html-母版
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.ioloop
import tornado.web
from controllers import extend

settings = {
    'template_path':'views', #配置模板文件路径
    'static_path':'statics', #配置静态文件路径
}
#路由映射
application = tornado.web.Application([
    (r"/index", extend.IndexHandler),
    (r"/fuckoff", extend.FuckOffHandler),

],**settings)   #**settings是让配置生效

#二级域名的配置
# application.add_handlers('buy.ssh.com$',[
#     (r"/index/(?P<page>\d*)",buy.IndexHandler)
# ])


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

 

posted @ 2018-07-19 13:58  I我的博客I  阅读(337)  评论(0编辑  收藏  举报