1.新建tornado项目

2.app.py项目配置文件
import tornado.ioloop
import tornado.web # web应用api
import tornado.options
from tornado.options import define, options
from handlers.main import IndexHandler
from handlers.users import RegisterHandler, LoginHandler
define('port', default='8889', help='Listening port', type=int)
class Application(tornado.web.Application):
def __init__(self):
handlers = [
(r'/', IndexHandler), # 首页
(r'/register', RegisterHandler), # 注册
(r'/login', LoginHandler), # 登录
]
settings = dict(
debug=True,
static_path='static', # 配置静态文件路径
template_path='templates', # 配置模板路径
cookie_secret='sadhdjh', # 设置cookie密钥,随便设置
xsrf_cookies=True, # 内置XSRF保护.
pycket={
'engine': 'redis',
'storage': {
'host': '127.0.0.1',
'port': 6379,
'db_sessions': 10,
'max_connections': 2 ** 31,
},
'cookies': {
# 设置过期时间
'expires_days': 2,
# 'expires':None, #秒
},
},
login_url='/login', # 如果用户没有登录, 用户将会被重定向到这个页面
)
super().__init__(handlers, **settings)
if __name__ == "__main__": # 只有在当前文件运行的时候才会执行
tornado.options.parse_command_line() # 命令行
app = Application() # 实例化
app.listen(options.port) # 端口
tornado.ioloop.IOLoop.current().start() # 开启tornado服务
3.handlers用来存放后台的处理程序
main.py
import tornado.web
import os
from pycket.session import SessionMixin
from models.auth import Image
from models.db import session
class BaseHandler(tornado.web.RequestHandler, SessionMixin):
'''
实现用户认证, 重写 get_current_user() 方法来判断当前用户,比如可以基于cookie的值
'''
def get_current_user(self):
return self.session.get('user')
class IndexHandler(tornado.web.RequestHandler):
'''
首页:用户上传图片的展示
'''
def get(self):
return self.write'这是首页')
user.py
import tornado.web
import re
from models.auth import User
from utils.encryption import passwd_encryption
from handlers.main import BaseHandler
class RegisterHandler(tornado.web.RequestHandler):
'''
注册
'''
def get(self):
return self.render('register.html')
def post(self):
# 1.获取前端参数
username = self.get_argument('username', '').strip()
password = self.get_argument('password', '').strip()
repeat_password = self.get_argument('repeat_password', '').strip()
# 2.校验参数
# 判断是否为空
if not all([username, password, repeat_password]):
return self.write('参数错误')
# 判断格式
if not(re.match('^\w{6,20}$', username) and password == repeat_password):
return self.write('格式错误')
# 判断用户是否已存在
if User.check_username(username):
return self.write('用户名已存在')
# 密码加密
passwd = passwd_encryption(password)
# 3.入库
User.add_user(username, passwd) # 保存user数据
# 4.返回数据给前端
return self.write('注册成功')
class LoginHandler(BaseHandler):
'''
登录
'''
def get(self):
return self.render('login.html')
def post(self):
# 1.获取用户名和密码
username = self.get_argument('username', '').strip()
password = self.get_argument('password', '').strip()
if username and password:
# 2.判断密码是否正确
user = User.check_username(username) # 获取用户实例
passwd = user.password if user else '' # 数据库中已经加密的密码
if passwd_encryption(password, passwd, False) == passwd.encode('utf8'):
self.session.set('user', username)
next = self.get_argument('next', '/') # 获取需登录前一个页面路由
return self.redirect(next) # 重定向到登录前一个页面
else:
return self.write('用户名或密码错误')
else:
self.write('参数错误')
# 3.设置会话
pass
4.models用来存放模型类
auth.py
from datetime import datetime
import os
import sys
# 把当前项目路径加入到path中
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
from models.db import Base, session
from sqlalchemy import Table
from sqlalchemy.orm import relationship
from sqlalchemy import Column, Integer, String, DateTime, Boolean, ForeignKey
class BaseModel:
is_delete = Column(Boolean, default=False)
create_time = Column(DateTime, default=datetime.now)
update_time = Column(DateTime, default=datetime.now)
class User(Base, BaseModel):
__tablename__ = 'users'
id = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(30), nullable=False, unique=True)
password = Column(String(200), nullable=False)
is_active = Column(Boolean, default=False)
email = Column(String(100))
phone = Column(String(30))
# 添加用户
@classmethod
def add_user(cls, username, password, **kwargs):
user = User(username=username, password=password, **kwargs)
session.add(user)
session.commit()
# 校验用户名是否已存在
@classmethod
def check_username(cls, username):
return session.query(cls).filter_by(username=username).first()
def __repr__(self):
return '<User:username=%s, password=%s>' % (self.username, self.password)
class Image(Base, BaseModel):
__tablename__ = 'images'
id = Column(Integer, primary_key=True, autoincrement=True)
image_url = Column(String(500))
user_id = Column(Integer, ForeignKey('users.id'))
user = relationship('User', backref='images', uselist=False, cascade='all') # 声明表关系
def __repr__(self):
return '<Images:user_id=%s>' % self.user_id# 图片实例.user ===> 拿到对应的user实例
# 用户实例.images ===> 拿到对应的图片实例
db.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'instagram'
USERNAME = 'root'
PASSWORD = 'qwe123'
# 然后设置一个字符串的格式:
db_url='mysql+pymysql://{}:{}@{}/{}?charset=utf8'.format(
USERNAME,
PASSWORD,
HOSTNAME,
DATABASE
)
# 创建一个引擎:
engine = create_engine(db_url)
# 将引擎作为参数导入declarative_base()方法,返回一个类:
Base = declarative_base(engine)
# 同时需要创建一个会话窗,即映射:
Session = sessionmaker(engine)
session = Session()
# 验证是否成功可以在尾端进行如下操作:
if __name__=='__main__':
print(dir(Base))
print(dir(session))
5.templates模板文件
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}
{% end %}</title>
{% block link %}
{% end %}
</head>
<body>
{% block body %}
{% end %}
{% block script %}
{% end %}
</body>
</html>
register.html
{% extends 'base.html' %}
{% block title %}
注册
{% end %}
{% block body %}
<form action="" method="post">
{% module xsrf_form_html() %} <!-- 跨站请求伪造(防护) -->
用户名:<input type="text" placeholder="请输入用户名" name="username"><br>
密 码:<input type="password" placeholder="请输入密码" name="password"><br>
密 码:<input type="password" placeholder="请再次输入密码" name="repeat_password"><br>
<button type="submit">注册</button>
</form>
{% end %}
login.html
{% extends 'base.html' %}
{% block title %}
登录
{% end %}
{% block body %}
<form action="" method="post">
{% module xsrf_form_html() %} <!-- 跨站请求伪造(防护) -->
用户名:<input type="text" placeholder="请输入用户名" name="username"><br>
密 码:<input type="password" placeholder="请输入密码" name="password"><br>
<button type="submit">登录</button>
</form>
{% end %}