目录结构
根目录下 07login.py
目录templates目录下:08sqlalchmy.html 08login.html 08register.html 04base.html
目录data目录下:connect.py user_modules.py
一、基础模型相关
1、数据库连接设置文件(请自行修正程序缩进,连接信息根据自身情况进行修正)
connect.py
from sqlalchemy import create_engine
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'mydb'
USERNAME = 'admin'
PASSWORD = 'Root110qwe'
db_url = 'mysql+pymysql://{}:{}@{}/{}?charset=utf8'.format(
USERNAME,
PASSWORD,
HOSTNAME,
DATABASE
)
engine = create_engine(db_url)
#创建映像
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base(engine)
#创建会话
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(engine)
session = Session()
# if __name__ == '__main__':
# print(dir(engine))
# print(dir(Base))
# print(dir(session))
2、模型创建 与 基本方法
user_modules.py
from datetime import datetime
from sqlalchemy import Column, Integer, String, DateTime, Boolean
from connect import Base, session
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True, autoincrement=True)
username = Column(String(20), nullable=False)
password = Column(String(50))
creatime = Column(DateTime, default=datetime.now)
_locked = Column(Boolean, default=False, nullable=False)
@classmethod
def all(cls):
return session.query(cls).all()
@classmethod
def by_id(cls, id):
return session.query(cls).filter_by(id=id).all()
@classmethod
def by_name(cls, name):
return session.query(cls).filter_by(username=name).all()
@property
def locked(self):
return self._locked
def __repr__(self):
return "<User (id='%s',username='%s',password='%s',creatime='%s',_locked_='%s')>" % (
self.id,
self.username,
self.password,
self.creatime,
self._locked
)
if __name__ == '__main__':
Base.metadata.create_all()#如果模型存在,重复执行也不会再次更新数据表模型
07login.py
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define, options
from data.user_modules import User, session
define('port', default=8000, help='run port', type=int)
class AuthError(Exception): # 自定义异常
def __init__(self, msg):
super(AuthError, self).__init__(msg)
class IndexHandler(tornado.web.RequestHandler):
def get(self):
username = 'no'
self.render('08sqlalchemy.html', username=username)
class RegisterHandler(tornado.web.RequestHandler):
def get(self):
self.render('08register.html', error=None)
def post(self):
if self._check_argeument():
try:
self._create_user()
self.render('08login.html', error='注册成功,请登录')
except AuthError as e:
self.render('08register.html', error=e)
except Exception as e:
self.render('08register.html', error=e)
else:
self.render('08register.html', error='您输入的用户名或密码格式有误')
def _check_argeument(self):
username = self.get_argument('name', '')
passwd = self.get_argument('password1', '')
if len(username) < 4 or len(passwd) < 6:
return False
if len(username) <= 10 and len(passwd) <= 10:
return True
else:
return False
def _create_user(self):
if self.get_argument('password1', '') != self.get_argument('password2', ''):
raise AuthError('两次输入的密码不同')
if User.by_name(self.get_argument('name', '')):
raise AuthError('用户名已经被注册 ,请更换后重试。')
user = User()
user.username = self.get_argument('name', '')
user.password = self.get_argument('password1', '')
session.add(user)
session.commit()
class LoginHandler(tornado.web.RequestHandler):
def get(self):
username = 'no'
self.render('08login.html', error=None)
def post(self):
username = User.by_name(self.get_argument('name', ''))
passwd = self.get_argument('password', '')
if username and username[0].password == passwd:
print('ok')
self.render('08sqlalchemy.html',
username=username[0].username)
else:
self.render('08login.html', error='登录失败,请检查用户名或密码后重试。')
if __name__ == '__main__':
tornado.options.parse_command_line()
app = tornado.web.Application(
handlers=[
(r'/', IndexHandler),
(r'/login', LoginHandler),
(r'/register', RegisterHandler),
],
debug=True, # 非常重要 存盘就自动应用在 server
template_path='templates', # html文件的文件夹
static_path='static',
autoescape=None, # 关闭自动转义
)
# 以下是固定的 记住就行
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
4、模板文件
用户中心页面
08sqlalchemy.html
{% extends "./04base.html" %}
{% block title %}
用户中心 - 用户管理
{% end %}}
{% block body%}
{% if username!='no' %}
登录成功:欢迎 {{ username }} 回来。<br>点击<a href="/">退出登录</a>
{% else %}
您还没有
<a href="/login">登录</a>,或进行<a href="/register">新用户注册</a>
{%end%}
{%end%}
注册页面
08register.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册 - 用户管理</title>
</head>
<body>注册新账号<br>如果有账号,请点击<a href="/login">登录</a> <br>
<p>
<form method="post" action="/register">
登录账号:<input type="text" name="name">
{%if error%}字数4位至10位{%end%}<br>
输入密码:<input type="password" name="password1">
{%if error%}字数6位至10位{%end%}<br>
确认密码:<input type="password" name="password2">
<input type="submit">
</form></p>
{%if error%}
提示:提交失败,{{error}}
{%end%}
</body>
</html>
登录页面
08login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录 - 用户管理</title>
</head>
<body>
登录
<br>如果没有账号,请点击<a href="/register">注册</a> <br>
<p>
<form method="post" action="/login">
账号:<input type="text" name="name"><br>
密码:<input type="password" name="password">
<input type="submit"><br></p>
{%if error%}
提示:{{error}}
{%end%}
</form>
</body>
</html>
模板基类文件
04base.html
<!DOCTYPE html>
{% autoescape None %}
{#整页不转义
局部转义 escape(htmlStr)
#}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}Tornado{%end%}</title>
<link rel="shortcut icon" href="{{ static_url('images/favicon.ico') }}" type="image/x-icon"/>
</head>
<body>
{% block body %}
this is base
{% end %}
</body>
</html>