1102 tornado

 

5-6 RequestHandler的子类

RedirectHandler

# 1. RedirectHandler
#  301是永久重定向, 302是临时重定向,获取用户个人信息, http://www.baidu.com https

 

self.redirect方法和RedirectHandler方法区别是什么

self.redirect

可以定义业务逻辑,并根据逻辑选择是否跳转

RedirectHandler

在 url 进来的时候,就跳转

 

StaticFileHandler 

配置静态文件的方式

方式一:

 这样配置,方便多个项目静态文件的配置。

settings = {
    "static_path": "D:/Users/wenyule/Documents/PythonCode/tornado-forum/tornado_overview/chapter02/static",
}

# 这样配置了,就要在创建APP实例的时候解包

 

if __name__ == "__main__":
    app = web.Application([
        ("/", MainHandler),
        ("/2/", RedirectHandler, {"url": "/"}),

    ], debug=True, **settings) # 解包

    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

 更改静态文件访问的前缀

settings = {
    "static_path": "D:/Users/wenyule/Documents/PythonCode/tornado-forum/tornado_overview/chapter02/static",
    "static_url_prefix": "/static1/"
}

方式二:

在url中配置

if __name__ == "__main__":
    app = web.Application([
        ("/", MainHandler),
        ("/2/", RedirectHandler, {"url": "/"}),
        ("/static3/(.*)", StaticFileHandler,
         {"path": "D:/Users/wenyule/Documents/PythonCode/tornado-forum/tornado_overview/chapter02/static"}),

    ], debug=True, )

    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

import time
import tornado
from tornado import web
from tornado.web import StaticFileHandler, RedirectHandler


# 1. RedirectHandler
# 1. 301是永久重定向, 302是临时重定向,获取用户个人信息, http://www.baidu.com https

# StaticFileHandler


# web.URLSpec


class MainHandler(web.RequestHandler):
    # 当客户端发起不同的http方法的时候, 只需要重载handler中的对应的方法即可
    async def get(self, *args, **kwargs):
        time.sleep(5)
        self.write("hello world")


class MainHandler2(web.RequestHandler):
    # 当客户端发起不同的http方法的时候, 只需要重载handler中的对应的方法即可
    async def get(self, *args, **kwargs):
        self.write("hello world2")


# 全局的静态文件配置目录
#
# settings = {
#     "static_path": "D:/Users/wenyule/Documents/PythonCode/tornado-forum/tornado_overview/chapter02/static",
#     "static_url_prefix": "/static1/"
# }
urls = [
    ("/", MainHandler),
    ("/2/", RedirectHandler, {"url": "/"}),
    ("/static3/(.*)", StaticFileHandler,
     {"path": "D:/Users/wenyule/Documents/PythonCode/tornado-forum/tornado_overview/chapter02/static"}),

]
if __name__ == "__main__":
    app = web.Application(urls, debug=True, )

    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

# self.redirect方法和RedirectHandler方法区别是什么
# self.redirect
完整演示代码

 5-7 tornado的template

传统的加载模板文件的方式

方式一

import tornado
from tornado.web import template
class MainHandler(web.RequestHandler):
    # 当客户端发起不同的http方法的时候, 只需要重载handler中的对应的方法即可
    async def get(self, *args, **kwargs):
    word = "hello bobboy"
    t = template.Template("<h1>{{ word }}</h2>")
    self.finish(t.generate(word=word))

方式二

import tornado
from tornado.web import template


class MainHandler(web.RequestHandler):
    async def get(self, *args, **kwargs):
        loader = template.Loader("hell.html")
        self.finish(loader.load("hello.html").generate(word=word))

高级正确的方式

settings = {
    "static_path":"C:/projects/tornado_overview/chapter02/static",
    "static_url_prefix":"/static2/",
    "template_path": "templates"  # 模板配置的路径
}

web框架都会有模板功能
django和tornado对于模板的思路或者理念是完全不一样的

class MainHandler(web.RequestHandler):
    async def get(self, *args, **kwargs):
        word = "hello bobboy"
        self.render("index.html", word=word)

 5-8 购物车列表页-template常用功能

 template 模板语法

变量: {{  }}
标签: {% %}


块标签: {% block name %}
      {% end %}

{% block custom_css %}
{% end %}

{% block custom_js %}
{% end %}

 注意 {% end %}结尾

 可以用作 base.html 页面留的钩子

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>网上超市</title>
    <link href="{{ static_url('css/public.css') }}" type="text/css" rel="stylesheet">
    <link rel="stylesheet" type="text/css" href="{{ static_url('css/base.css') }}">
    <link rel="stylesheet" type="text/css" href="{{ static_url('css/checkOut.css') }}">
    {% block custom_css %}
    {% end %}
</head>

<body>
<!--顶部快捷菜单-->
<div class="shortcut_v2013 alink_v2013">
    <div class="w">
        <ul class="fl 1h">

            <li class="fl"><i class="shortcut_s"></i></li>

            <li class="fl">
                <div class="menu_hd"><a href="#">请登录</a></div>
            </li>
            <li class="fl">
                <div class="menu_hd"><a href="#">免费注册</a></div>
            </li>
        </ul>
        <ul class="fr 1h">
            <li class="fl">
                <div class="menu_hd"><a href="#">我的订单</a></div>
            </li>
            <li class="fl"><i class="shortcut_s"></i></li>
            <li class="fl">
                <div class="menu_hd"><a href="#">我的锡货</a></div>
            </li>
            <li class="fl"><i class="shortcut_s"></i></li>
            <li class="fl">
                <div class="menu_hd"><a href="#">服务中心</a></div>
            </li>
            <li class="fl"><i class="shortcut_s"></i></li>
            <li class="fl">
                <div class="menu_hd"><a href="#">商家入驻</a></div>
            </li>
            <li class="fl"><i class="shortcut_s"></i></li>
            <li class="fl">
                <div class="menu">
                    <div class="menu_hd"><a href="#">网站导航</a><b><em></em></b></div>
                    <div class="menu_bd">
                        <ul>
                            <li><a href="#">网站导航</a></li>
                            <li><a href="#">网站导航</a></li>
                        </ul>
                    </div>
                </div>
            </li>
        </ul>
        <span class="clr"></span>
    </div>
</div>

<div class="banner_red_top"></div>
{% block body %}
<h2>bobby</h2>
{% end %}
<div class="promise_box">
    <div class="w">
        <ul>
            <li><img src="{{ static_url('images/promise_img01.jpg') }}"><span>365天不打烊</span></li>
            <li><img src="{{ static_url('images/promise_img02.jpg') }}"><span>无理由退换货</span></li>
            <li><img src="{{ static_url('images/promise_img03.jpg') }}"><span>担保交易</span></li>
            <li><img src="{{ static_url('images/promise_img04.jpg') }}"><span>先行赔付</span></li>
            <li><img src="{{ static_url('images/promise_img05.jpg') }}"><span>支持定制</span></li>
        </ul>
    </div>
</div>

<div class="footer_v2013 bottom-about">
    <div class="w">
        <p class="foot_p1">
            <a href="#">首页</a>|<a href="#">招聘英才</a>|<a href="#">广告合作</a>|<a href="#">联系我们</a>|<a href="#">关于我们</a>
        </p>
        <pre>    经营许可证:ICP备13041162号-1360网站安全检测平台
                </pre>
    </div>
</div>
{% block custom_js %}
{% end %}
</body>
</html>
base.html

  {% extends 'base.html' %} 

 像编写Python程序一样,在HTML文件里面写逻辑

{% if total > 200%}
<h1>钱不够</h1>
{% else %}
<h1> 买买 </h1>
{% end %}

 

{% extends 'base.html' %}
{% block body %}
<div class="border_top_cart">
    <div class="container">
        <div class="checkout-box">
            <form id="checkoutForm" action="#" method="post">

                <div class="checkout-box-ft">
                    <div id="checkoutGoodsList" class="checkout-goods-box">
                        <div class="xm-box">
                            <div class="box-hd">
                                <h2 class="title">确认订单信息</h2>
                            </div>
                            <div class="box-bd">
                                <dl class="checkout-goods-list">
                                    <dt class="clearfix">
                                        <span class="col col-1">商品名称</span>
                                        <span class="col col-2">购买价格</span>
                                        <span class="col col-3">购买数量</span>
                                        <span class="col col-4">小计(元)</span>
                                    </dt>
                                    {% set total = 0 %}
                                    {% for order in orders %}
                                    <dd class="item clearfix">
                                        <div class="item-row">
                                            <div class="col col-1">
                                                <div class="g-pic">
                                                    <img src="{{ order['image'] }}" srcset="{{ order['image'] }} 2x"
                                                         width="40" height="40">
                                                </div>
                                                <div class="g-info">{{ order['name'] }}</a></div>
                                            </div>
                                            {{ total = total+order['price']*order['nums'] }}
                                            {% from chapter02.utils import cal_total %}
                                            <div class="col col-2">{{ order['price'] }}元</div>
                                            <div class="col col-2">{{ order['nums'] }}</div>
                                            <div class="col col-2">{{ cal_total(order['price'],order['nums']) }}元</div>
                                            <div class="col col-2">{% raw order['detail'] %}</div>
                                        </div>
                                    </dd>
                                    {% end %}

                                </dl>
                                <div class="checkout-count clearfix">

                                    <div class="checkout-price">
                                        <ul>
                                            <li>
                                                订单总额:<span>{{ total }}元</span>
                                            </li>
                                            <li>
                                                运费:<span id="postageDesc">0元</span>
                                            </li>
                                        </ul>
                                        <p class="checkout-total">应付总额:<span><strong
                                                id="totalPrice">{{ total }}</strong></span></p>
                                    </div>
                                    <!--  -->
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </form>
        </div>

    </div>
</div>
{% end %}
shop_car.html

 后端处理逻辑

# 1. 什么是模板
from tornado.web import StaticFileHandler, RedirectHandler

# 1. RedirectHandler
# 1. 301是永久重定向, 302是临时重定向,获取用户个人信息, http://www.baidu.com https

# StaticFileHandler
import time

from tornado import web
import tornado
from tornado.web import template


class MainHandler(web.RequestHandler):
    # 当客户端发起不同的http方法的时候, 只需要重载handler中的对应的方法即可
    async def get(self, *args, **kwargs):
        # web框架都会有模板功能
        # django和tornado对于模板的思路或者理念是完全不一样的
        orders = [
            {
                "name": "小米T恤 忍者米兔双截棍 军绿 XXL",
                "image": "http://i1.mifile.cn/a1/T11lLgB5YT1RXrhCrK!40x40.jpg",
                "price": 39,
                "nums": 3,
                "detail": "<a href='http://www.baidu.com'>查看详情</a>"
            },
            {
                "name": "招财猫米兔 白色",
                "image": "http://i1.mifile.cn/a1/T14BLvBKJT1RXrhCrK!40x40.jpg",
                "price": 49,
                "nums": 2,
                "detail": "<a href='http://www.baidu.com'>查看详情</a>"
            },
            {
                "name": "小米圆领纯色T恤 男款 红色 XXL",
                "image": "http://i1.mifile.cn/a1/T1rrDgB4DT1RXrhCrK!40x40.jpg",
                "price": 59,
                "nums": 1,
                "detail": "<a href='http://www.baidu.com'>查看详情</a>"
            }
        ]
        self.render("index.html", orders=orders)
        # word = "hello bobboy"
        # t = template.Template("<h1>{{ word }}</h2>")
        # self.finish(t.generate(word=word))
        #
        # loader = template.Loader("hell.html")
        # self.finish(loader.load("hello.html").generate(word=word))


class MainHandler2(web.RequestHandler):
    # 当客户端发起不同的http方法的时候, 只需要重载handler中的对应的方法即可
    async def get(self, *args, **kwargs):
        self.write("hello world2")


settings = {
    "static_path": "D:/Users/wenyule/Documents/PythonCode/tornado-forum/tornado_overview/chapter02/static",
    "static_url_prefix": "/static2/",
    "template_path": "templates"
}

if __name__ == "__main__":
    app = web.Application([
        ("/", MainHandler),
        ("/2/", RedirectHandler, {"url": "/"}),
        ("/static/(.*)", StaticFileHandler, {"path": "C:/projects/tornado_overview/chapter02/static"})
    ], debug=True, **settings)
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

# self.redirect方法和RedirectHandler方法区别是什么
# self.redirect
template_test.py

5-9 template之页面继承和重载

5-10 tornado模板中UIModule

 

import tornado
from tornado import web
from tornado.web import StaticFileHandler


class OrderModule(tornado.web.UIModule):
    def cal_total(self, price, nums):
        return price * nums

    def render(self, order, *args, **kwargs):
        """
        反回渲染
        :param order:  传入的参数
        :param args:
        :param kwargs:
        :return:
        """
        return self.render_string("ui_modules/order-list.html", order=order, cal_total=self.cal_total)

    def embedded_css(self):
        return "body {background-color:green}"


class MainHandler(web.RequestHandler):
    # 当客户端发起不同的http方法的时候, 只需要重载handler中的对应的方法即可
    async def get(self, *args, **kwargs):
        # web框架都会有模板功能
        # django和tornado对于模板的思路或者理念是完全不一样的
        orders = [
            {
                "name": "小米T恤 忍者米兔双截棍 军绿 XXL",
                "image": "http://i1.mifile.cn/a1/T11lLgB5YT1RXrhCrK!40x40.jpg",
                "price": 39,
                "nums": 3,
                "detail": "<a href='http://www.baidu.com'>查看详情</a>"
            },
            {
                "name": "招财猫米兔 白色",
                "image": "http://i1.mifile.cn/a1/T14BLvBKJT1RXrhCrK!40x40.jpg",
                "price": 49,
                "nums": 2,
                "detail": "<a href='http://www.baidu.com'>查看详情</a>"
            },
            {
                "name": "小米圆领纯色T恤 男款 红色 XXL",
                "image": "http://i1.mifile.cn/a1/T1rrDgB4DT1RXrhCrK!40x40.jpg",
                "price": 59,
                "nums": 1,
                "detail": "<a href='http://www.baidu.com'>查看详情</a>"
            }
        ]
        self.render("index2.html", orders=orders)


settings = {
    "static_path": "D:/Users/wenyule/Documents/PythonCode/tornado-forum/tornado_overview/chapter02/static",
    "static_url_prefix": "/static2/",
    "template_path": "templates",
    "ui_modules": {
        "OrderModule": OrderModule
    }
}

if __name__ == "__main__":
    app = web.Application([
        ("/", MainHandler),
        ("/static/(.*)", StaticFileHandler,
         {"path": "D:/Users/wenyule/Documents/PythonCode/tornado-forum/tornado_overview/chapter02/static"})
    ], debug=True, **settings)
    app.listen(9999)
    tornado.ioloop.IOLoop.current().start()
uimodule_test.py

 

settings = {
    "static_path": "C:/projects/tornado_overview/chapter02/static",
    "static_url_prefix": "/static2/",
    "template_path": "templates",
    "ui_modules": {
        "OrderModule": OrderModule    # 配置文件,传到app里面去
    }
}

if __name__ == "__main__":
    app = web.Application([
        ("/", MainHandler),
        ("/2/", RedirectHandler, {"url": "/"}),
        ("/static/(.*)", StaticFileHandler, {"path": "C:/projects/tornado_overview/chapter02/static"})
    ], debug=True, **settings)
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

 

 定义一个处理html模块的类

class OrderModule(tornado.web.UIModule):
    def cal_total(self, price, nums):  # 自定义一个函数
        return price * nums

    def render(self, order, *args, **kwargs):
        """
        反回渲染
        :param order:  传入的参数
        :param args:
        :param kwargs:
        :return:
        """
        return self.render_string("ui_modules/order-list.html", order=order, cal_total=self.cal_total)

    def embedded_css(self):
        return "body {background-color:green}"

 

主要的部分

{% extends 'base.html' %}
{% block body %}
<div class="border_top_cart">
    <div class="container">
        <div class="checkout-box">
            <form id="checkoutForm" action="#" method="post">

                <div class="checkout-box-ft">
                    <div id="checkoutGoodsList" class="checkout-goods-box">
                        <div class="xm-box">
                            <div class="box-hd">
                                <h2 class="title">确认订单信息</h2>
                            </div>
                            <div class="box-bd">
                                <dl class="checkout-goods-list">
                                    <dt class="clearfix">
                                        <span class="col col-1">商品名称</span>
                                        <span class="col col-2">购买价格</span>
                                        <span class="col col-3">购买数量</span>
                                        <span class="col col-4">小计(元)</span>
                                    </dt>
                                    {% set total = 0 %}
                                    {% for order in orders %}
                                        {% module OrderModule(order) %}
                                    {% end %}

                                </dl>
                                <div class="checkout-count clearfix">

                                    <div class="checkout-price">
                                        <ul>
                                            <li>
                                                订单总额:<span>{{ total }}元</span>
                                            </li>
                                            <li>
                                                运费:<span id="postageDesc">0元</span>
                                            </li>
                                        </ul>
                                        <p class="checkout-total">应付总额:<span><strong
                                                id="totalPrice">{{ total }}</strong></span></p>
                                    </div>

                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </form>
        </div>

    </div>
</div>
{% end %}
主要的部分

 

模块化的部分

<dd class="item clearfix">
    <div class="item-row">
        <div class="col col-1">
            <div class="g-pic">
                <img src="{{ order['image'] }}" srcset="{{ order['image'] }} 2x" width="40" height="40">
            </div>
            <div class="g-info">{{ order['name'] }}</a></div>
        </div>
        {% from chapter02.utils import cal_total %}
        <div class="col col-2">{{ order['price'] }}元</div>
        <div class="col col-2">{{ order['nums'] }}</div>
        <div class="col col-2">{{ cal_total(order['price'],order['nums']) }}元</div>
        <div class="col col-2">{% raw order['detail'] %}</div>
    </div>
</dd>
order-list.html

 

 

 

 

 

 

5-11 tornado的settings

 

 

6-2 aiomysql完成数据的读写

异步 mysql 操作的模块 

 pip install aiomysql  

Python 3.7 以后 async 已经是内置标识符 可以直接使用,不用再导入  import asyncio 

import asyncio
from tornado import ioloop
from aiomysql import create_pool

async def go():
    async with create_pool(host='127.0.0.1', port=3306,
                           user='root', password='123456',
                           db='message', charset="utf8") as pool:
        async with pool.acquire() as conn:
            async with conn.cursor() as cur:
                await cur.execute("SELECT * from message")
                value = await cur.fetchone()
                print(value)

if __name__ == "__main__":

    io_loop = ioloop.IOLoop.current()
    io_loop.run_sync(go)
操作数据库例子

 

 

 

6-3 数据的提交和修改

import tornado
from tornado import web
from aiomysql import create_pool


class MainHandler(web.RequestHandler):
    def initialize(self, db):
        self.db = db

    async def get(self, *args, **kwargs):
        id = ""
        name = ""
        email = ""
        address = ""
        message = ""
        async with create_pool(host=self.db["host"], port=self.db["port"],
                               user=self.db["user"], password=self.db["password"],
                               db=self.db["name"], charset="utf8") as pool:
            async with pool.acquire() as conn:
                async with conn.cursor() as cur:
                    await cur.execute("SELECT id, name, email, address, message from message")
                    try:
                        id, name, email, address, message = await cur.fetchone()
                    except Exception as e:
                        pass
        self.render("message.html", id=id, email=email, name=name, address=address, message=message)

    async def post(self, *args, **kwargs):
        id = self.get_body_argument("id", "")
        name = self.get_body_argument("name", "")
        email = self.get_body_argument("email", "")
        address = self.get_body_argument("address", "")
        message = self.get_body_argument("message", "")

        async with create_pool(host=self.db["host"], port=self.db["port"],
                               user=self.db["user"], password=self.db["password"],
                               db=self.db["name"], charset="utf8") as pool:
            async with pool.acquire() as conn:
                async with conn.cursor() as cur:
                    if not id:
                        await cur.execute(
                            "INSERT INTO message(name, email, address, message) VALUES('{}','{}','{}','{}')".format(
                                name,
                                email,
                                address,
                                message))
                        await cur.execute("SELECT id from message where name='{}'".format(name))
                        try:
                            id = await cur.fetchone()
                        except Exception as e:
                            pass
                    else:
                        await cur.execute(
                            "update message set name='{}', email='{}', address='{}', message='{}'".format(name, email,
                                                                                                          address,
                                                                                                          message))
                    await conn.commit()
        self.render("message.html", id=id, email=email, name=name, address=address, message=message)


settings = {
    "static_path": "D:/Users/wenyule/Documents/PythonCode/tornado-forum/tornado_overview/chapter03/static",
    "static_url_prefix": "/static/",
    "template_path": "templates",
    "db": {
        "host": "127.0.0.1",
        "user": "root",
        "password": "123456",
        "name": "message",
        "port": 3306
    }
}

if __name__ == "__main__":
    app = web.Application([
        ("/", MainHandler, {"db": settings["db"]}),
    ], debug=True, **settings)
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()
完整代码

 

 

 

 

 

 

 

 

7-3 model的数据保存

 

 

 import peewee_async # 异步orm 

使用异步的数据库连接以后就不能再以同步的方式去编程

 

from datetime import datetime

from peewee import *
from peewee import Model
import peewee_async  # 异步orm

db = MySQLDatabase('message', host="127.0.0.1", port=3306, user="root", password="123456")

# 异步的数据库连接
database = peewee_async.MySQLDatabase(
    'message', host="127.0.0.1", port=3306, user="root", password="123456"
)

objects = peewee_async.Manager(database)

# No need for sync anymore!


database.set_allow_sync(False)  # 设置非同步


class BaseModel(Model):
    add_time = DateTimeField(default=datetime.now, verbose_name="添加时间")

    class Meta:
        # database = database #异步的数据库连接
        database = db


class Supplier(BaseModel):
    name = CharField(max_length=100, verbose_name="名称", index=True)
    address = CharField(max_length=100, verbose_name="联系地址")
    phone = CharField(max_length=11, verbose_name="联系方式")

    class Meta:
        database = db
        table_name = "supplier"


class Goods(BaseModel):
    supplier = ForeignKeyField(Supplier, verbose_name="商家", backref="goods")
    name = CharField(max_length=100, verbose_name="商品名称", index=True)
    click_num = IntegerField(default=0, verbose_name="点击数")
    goods_num = IntegerField(default=0, verbose_name="库存数")
    price = FloatField(default=0.0, verbose_name="价格")
    brief = TextField(verbose_name="商品简介")

    class Meta:
        table_name = "goods"


def init_table():
    db.create_tables([Goods, Supplier])


if __name__ == "__main__":
    init_table()
model.py

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2020-11-03 00:29  元贞  阅读(29)  评论(0)    收藏  举报