一,项目模板:
Tornado的项目也可以像Django和flask一样,将功能细分为几个模块
├── app
│ ├── __init__.py #创建应用
│ ├── setting.py #相关文件的配置
│ ├── urls.py #url放的地方
│ └── views.py #类视图放的地方
├── manage.py #运行app
├── static #静态文件
| ├── css #css文件放的地方
| └── js #js文件放的地方
└── templates #模板
└── index.html
1.1 _ _ init _ _.py
import tornado.web
from app.settings import BASE_DIR
import os
from tornado.options import options
from app.views import *
from app.urls import urlpatterns
#创建app,用它来启动我们的服务器
def make_app():
return tornado.web.Application(
handlers=urlpatterns, # url
template_path=os.path.join(BASE_DIR, 'templates'), #模板文件路径
static_path=os.path.join(BASE_DIR, 'static'), #静态文件路径
debug=options.debug, #调试模式
)
1.2 setting .py
import os
# 取到项目根路径
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
1.3 urls .py
from tornado.web import url
from app.views import *
#路径列表
urlpatterns=[
url(r'/index/', MainHandler,name='index'), #路径
]
1.4 views .py
import tornado.web
# 类视图 MTV -V
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.render('index.html')
1.5 manage .py
import tornado.ioloop
from tornado.options import options,define,parse_command_line
# define 定义端口的选项 options 创建这些选项 parse_command_line 解释命令行
from app.__init_ import make_app
#设置默认端口
define('port',default=8888)
#调试模式
define('debug',default=True)
#解释命令行
parse_command_line()
#创建应用,用它来启动我们的服务器
app=make_app()
#绑定监听端口
app.listen(options.port)
# 开启web应用程序
tornado.ioloop.IOLoop.current().start()
将这个模板拷贝下来,以后创建新项目的时候可以直接拷贝一份,在此模板上修改使用
文件链接
链接:https://pan.baidu.com/s/11EqHXvr-Y8dPzMAxqkMmuw
提取码:m33t
二,模板语法:
和django,flask语法类似 不同在于结束标签就end就只有{% end %}即可
2.1 挖坑
{% block title %}
{% end %}
继承
{% extends 'base.html' %}
{% block css %}
<!--第一种加载方式: 直接定义静态文件的路径-->
<!--<link rel="stylesheet" href="/static/css/style.css">-->
<!--第二种加载方式-->
<link rel="stylesheet" href="{{ static_url('css/style.css') }}">
{% end %}
2.2逻辑:
标签: {% 标签名 %} {% end %}
2.2.1 if标签:
1.
{% if 条件%}
{% end %}
2.
{% if 条件 %}
{% elif 条件%}
{% else %}
{% end %}
2.2.2 for标签:
{% for 变量 in [] %}
{% end %}
2.3变量:
变量: {{ 变量名 }}
2.4注释:
注解: {# 注解内容 #}
三 . 模型:
tornado,没有集成orm对象,我们可以调用第三方的库,sqlalchemy
安装
pip install sqlalchemy
3.1 在终端创建一个新的mysql数据库,使用pycharm连接上数据库
3.2 在项目根路径下创建一个utils文件夹,再创建一个conn.py文件
conn .py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
# 连接数据库格式
# uri 资源类型+驱动://用户名:密码@主机名:端口号/数据库名
db_url='mysql+pymysql://zhangbo:123456@127.0.0.1:3306/tornadodb'
# 创建一个orm引擎 建立连接
engine = create_engine(db_url)
# orm类,继承的基类 模型与数据库表进行关联的基类,模型必须继承于Base
Base =declarative_base(bind=engine)
# 创建sql,会话对象session,可以session来CRUD
DBsession = sessionmaker(bind=engine)
session = DBsession()
3.3 创建模型 Person
tornado没有Django数据迁移的功能,所以如果创建的表要增加字段,只能删除表,然后再创建.而删除表,其中的数据也就没了
可以选择在终端使用mysql语句添加字段
3.3.1 在app文件夹下创建models .py文件
from utils.conn import Base
from sqlalchemy import Column,Integer,String,DateTime
# 通过类来在数据库中创建表,有几个类创建几个表
def create_all():
# 映射模型对应的表
Base.metadata.create_all()
# 删除所有的表
def drop_all():
# 删除模型映射的表
Base.metadata.drop_all()
class Person(Base):
# 字段名 id int型 主键=真 自增=真
id=Column(Integer,primary_key=True,autoincrement=True)
# 字符串类型 长度20
name=Column(String(20))
# 年龄 int型 默认值18
age=Column(Integer,default=18)
# 出生日期 DateTime型
birthday=Column(DateTime)
# 在数据库中保存的表名
__tablename__='person'
3.3.2 创建表和删除表
可以在底部的 Python console 栏输入命令
from app.models import *
create_all() #创建所有表
drop_all() #删除所有表
可以在右侧的Dataase栏查看表的状态变化
四. 数据的增删改查
4.1 增加
4.1.1 在在右侧的Dataase栏点开表直接操作
4.1.2 在底部Python console使用命令方式
#添加(id是自增的,可以不用写)
from app.models import Person #导入Person
from utils.conn import session #导入session
p=Person() #新建一个对象
p.name='小明'
p.age=18
p.birthday='1999-05-13'
session.add(p) #通过session添加对象
session.commit() #提交
然后可以在数据库中查看,添加了一条数据
4.1.3 通过视图的方式用post提交
在views.py文件下导入session
from utils.conn import session
在views.py文件下新建一个类视图
class PersonHandler(tornado.web.RequestHandler):
def post(self):
name=self.get_body_argument('name')
age=self.get_body_argument('age')
birthday=self.get_body_argument('birthday')
p=Person()
p.name=name
p.age=age
p.birthday=birthday
#增加
session.add(p)
# 提交
session.commit()
self.write('add person success')
在urls.py文件下添加一条url
url(r'/persons/', PersonHandler,name='person'),
在终端输入命令
curl -X POST 127.0.0.1:8888/persons/ -d'name=xiaoming&age=20&birthday=2000-05-03'
终端会得到提示 add person success,数据库中可以看到这条数据增加成功
4.1.4 通过视图的方式用get增加多条数据
在views.py文件下的 PersonHandler类试图下添加get方法
def get(self):
p_list=[]
for i in range(30):
p=Person()
p.name='老王'+str(i)
p.age=60-i
p.birthday='1980-10-10'
p_list.append(p)
try:
session.add_all(p_list)
session.commit()
except Exception as e:
print(e)
# 回滚
session.rollback()
self.write('add persons success')
然后在浏览器的地址栏中输入url
http://127.0.0.1:8888/persons/
页面上会返回 add persons success
查看数据库添加了30条数据
4.2 查询
4.2.1 在底部Python console使用命令方式
4.2.1.1 根据id查询,获取一个类的对象
from app.models import Person
from utils.conn import session
session.query(Person).get(5)
#<app.models.Person at 0x7f402621d978>
#得到的是一个对象,把这个对象赋给p接收一下,可以去获取这个对象身上的属性
p=session.query(Person).get(5)
p.name
# 得到 '老王2'
p.age
# 得到 58
4.2.1.2 根据filter_by批量查询
from app.models import Person
from utils.conn import session
#查找生日是 1980-10-10 00:00:00
session.query(Person).filter_by(birthday='1980-10-10 00:00:00')
#得到的是一个查询集 <sqlalchemy.orm.query.Query at 0x7f023b41f320>
session.query(Person).filter_by(birthday='1980-10-10 00:00:00').all()
#得到是一个列表,列表里面有30个对象
session.query(Person).filter_by(birthday='1980-10-10 00:00:00').all()[0].name
#获取列表里的第一个对象的名字 得到 '老王0'
效果等同于
session.query(Person).filter(Person.birthday=='1980-10-10 00:00:00').first().name
4.2.1.3 根据filter根据条件批量查询
session.query(Person).filter(Person.age<=20)
#得到的是一个查询集
#count() 计数
session.query(Person).filter(Person.age<=20).count()
#得到的是对象的数量 2
session.query(Person).filter(Person.age<=20).all()
#得到的是一个列表,列表里有两个对象
[<app.models.Person at 0x7f023b431a20>, <app.models.Person at 0x7f024946b1d0>]
#### startswith 以'''开头 ; endswith以'''结尾 ;contains 包含''' ####
session.query(Person).filter(Person.name.startswith('老')).count()
#得到名字以 '老' 开头的数量 30
session.query(Person).filter(Person.name.startswith('老')).all()[0].name
#得到名字以 '老' 开头的第一个对象的名字 '老王0'
相当于
session.query(Person).filter(Person.name.startswith('老')).first().name
#### and or not ####
session.query(Person).filter(Person.age>40,Person.age<60).count()
#取到年龄大于40和小于60的数量
可以去打印一下这些对象的名字
persons=session.query(Person).filter(Person.age>40,Person.age<60).all()
for person in persons:
print(person.name)
也可以把这些名字用列表的方式打印
[person.name for person in persons]
from sqlalchemy import or_,not_
#取到年龄小于20或大于50的人的名字
persons=session.query(Person).filter(or_(Person.age<20,Person.age>50)).all()
[person.name for person in persons]
得到
['小明', '老王0', '老王1', '老王2', '老王3', '老王4', '老王5', '老王6', '老王7', '老王8', '老王9']
#取到年龄不大于20的人的名字
persons=session.query(Person).filter(not_(Person.age>20)).all()
[person.name for person in persons]
得到
['小明', 'xiaoming']
4.2.2 通过类函数获得
在views.py文件下的PersonHandler类视图下添加方法
#取到年龄不大于20的人的名字
def put(self):
persons = session.query(Person).filter(not_(Person.age > 20)).all()
names = [person.name for person in persons]
print(names)
self.write('get names ok')
然后在终端输入命令
curl -X PUT 127.0.0.1:8888/persons/
终端会显示 get names ok,
pycharm会显示名字
(无比鸡肋的方法)
这里可以改一下,返回json字符串,给它序列化一下
def put(self):
persons = session.query(Person).filter(not_(Person.age > 20)).all()
names = [person.name for person in persons]
data={
'names':names,
'status':1,
}
# print(names)
self.write(json.dumps(data))
在终端再输入一下命令
curl -X PUT 127.0.0.1:8888/persons/
然后会在终端返回
#这里显示不了中文
{"names": ["\u5c0f\u660e", "xiaoming"], "status": 1}
好像更鸡肋了!!!
删除和更改都是可以先根据查询到相应的内容后再操作,但删除和修改不同于查询,数据变更需要提交
4.3 删除
4.3.1 根据查询语句删除
from app.models import Person
from utils.conn import session
from sqlalchemy import or_,not
#删除年龄不大于20的人
persons=session.query(Person).filter(not_(Person.age>20)).delete()
#可以查看一下删除了多少
persons
# 结果 2
#提交修改
session.commit()
可以查看一下数据库,删除了两条信息
4.3.2 通过对象删除
#删除id为5的人的数据
person = session.query(Person).get(5)
session.delete(person)
session.commit()
4.4 更改
4.4.1 根据查询语句修改
#更新年龄为40的人,把名字改为小王 ,年龄改为18 更新的内容是一个字典的形式
session.query(Person).filter_by(age=40).update({'name':'小王','age':18})
# 显示 1 表示修改一行 然后去提交
session.commit()
4.4.2 通过对象修改
#将id为20的名字改为 王一
person = session.query(Person).get(20)
person.name='王一'
session.commit()
4.5 将人渲染到页面上
在views.py文件下的类试图MainHandler中添加persons
class MainHandler(tornado.web.RequestHandler):
def get(self):
persons =session.query(Person).all()
self.render('index.html',persons=persons)
然后在index.html页面上展示这些信息
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>首页</h3>
{% for person in persons %}
<li>
姓名:{{ person.name }}
年龄:{{ person.age }}
</li>
{% end %}
</body>
</html>
在浏览器地址栏中输入url
文件链接
链接:https://pan.baidu.com/s/1Bxrw8mO55b8xKCBKZkQZQw
提取码:kt16