潭州课堂25班:Ph201805201 tornado 项目 第四课 增加用户注册登录(课堂笔记)
tornado 相关说明
在 handlers 中创建个 auth.py 用来做用户登录,在这文件中创建个类,并逐步完善
在 tornado 中创建 login.html 文件,是个登录页面
{% extends 'base.html' %}
{% block title %}登录{% end %}
{% block content %}
<h3>登录首页</h3>
<form action="/login" method="post" enctype="multipart/form-data">
<p>用户名:<input type="text" name="username" placeholder="请输入用户名" required=""></p>
<p>密 码:<input type="password" name="password" placeholder="请输入密码" required=""></p>
<button>登录</button>
</form>
{% end %}
在 app.py 的路由配置中添加登录页面的
实现密码加密,
在 utlis 中创建个 auth.py 文件,这个auth 是用来做密码处理的,
import hashlib # 对密码进行 md5 处理
def hashed(text):
"""哈西处理"""
return hashlib.md5(text.encode('utf8')).hexdigest()
USER_DATA = {
'username':'abc',
'password':hashed('123')
}
def authenticate(username, password):
"""
校验用户名,密码
:return True or False
"""
if username and password:
is_match = (username==USER_DATA['username'])and (hashed(password)==USER_DATA['password'])
return is_match
else:return False
所有 pip install 需要 workon env 之后执行
pip install pycket
python 与 redis 数据库连接,用 redis 存放相关信息
在 app.py 文件的配置中添加 cookie_secret = 字符串(随便填)
再加入如下字典
pycket={ 'engine': 'redis', # 引擎 'storage': { 'host': 'localhost', # 本地数据库 'port': 6379, # 端口 # 'password': '', 'db_sessions': 5, # redis db index # 'db_notifications': 11, 'max_connections': 2 ** 30, # 最大连接数 }, 'cookies': { # 'expires': 30, # 过期时间 (秒) 'expires_days': 30, # 过期时间 (天) }, } # static_url_prefix = '/pics/', )
在 handlers 的 auth.py 中的 导入 pycket
在 handlers 的 auth.py 中的 LoginHandler 改为多个继承
这样就添加了 cookie
拿信息
开始用户认证代码的完善,
在 main.py 中写个 AuthBaseHandler 多个继承的基础类,
这样在下面的 Handler 类中就可以直接继承这个类,实现用户认证
这样也可以对上述 login 代码进行优化,
如果要让一个页面只有在用户登录后才能查看,那就可以在这个方法的上边加个装饰器,
要让这个装饰器功能实现,还要在 app.py 文件的 配置中添加 login_url = '/login',
@tornado.web.authenticated
这时只有在用户登录后才能查看这个页面,
用户登出
在 handlers 的 auth.py 中添加用户退出登录类,
在 appp.py 的路由中添加路由
用户注册:
先要对数据库的连接
创建个库:create database tor
SQLalchemy 版本迁移工具 alembic 使用
进入虚拟环境,安装用到的包
pip install pymysql
pip install sqlalchemy
创建个包,名为 models
创建个 py 文件名为 db.py, 写数据库的连接信息
from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker HOST = '127.0.0.1' PORT = '3306' DATABASE = 'tor' USERNAME = 'admin' PASSWORD = 'Root110qwe' # 指定数据库类型,驱动, DB_URL = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format( USERNAME, PASSWORD, HOST, PORT, DATABASE ) engine = create_engine(DB_URL) DBSession = sessionmaker(bind=engine) Base = declarative_base(engine)
创建 account.py 文件
from datetime import datetime from sqlalchemy import (Column,Integer, String, DateTime) from .db import Base class User(Base): __tablename__ = 'users' # 主键,自增长, id = Column(Integer, primary_key=True, autoincrement=True) # 唯一的,不可以为空 name = Column(String(100), unique=True, nullable=False) # 密码 不是空的 password = Column(String(100), nullable=False) # 创建时间 creatd = Column(DateTime, default=datetime.now) def __repr__(self): return '<User(#{}: {})'.format(self.id, self.name)
alembic 初始化和配置
用 pychram 把文件下载回电脑,
可以提交下版本,
修改 alembic.ini 配置
连接数据库的 url
修改 env.py
告之 Base 类的位置,
完成 pip 安装之后
-
在 shell 里面 cd 到项目根目录执行
alembic init alembic
-
用 pycharm 把生成的文件 download 回来(包括
alembic
目录和alembic.ini
) -
修改
alembic.ini
设置数据库连接。sqlalchemy.url = driver://user:pass@localhost/dbname
-
在
env.py
中设置,将target_metadata赋值成数据库的元数据(metadata) 如果执行 revision 有 import 报错,注意是否正确将当前项目目录添加到 sys.path 路径
基于数据库 model 定义进行更新
将 model 定义好,并确认在 env.py 里导入的 Base 类是在 model 定义的地方的
-
配置完成执行( -m "注释信息",根据情况更改,会用到生成的py文件名字里)
alembic revision --autogenerate -m "create_user_table"
-
这里可以看到虚拟机目录在 alembic/versions 里生成了 py 文件,检查确认更新的内容,然后执行
alembic upgrade head
- 运行成功后,将会在这个表中生成一条记录,
-
-
这样就会更新 mysql 数据库了
命令参考
查看记录和历史
alembic history
回退上一个升级的版本
alembic downgrade -1
查看生成的 py 文件
ls -l alembic/versions
其他操作
-
删除 rm alembic/versions/xxx.py
常见问题
执行 alembic 报错,KeyError:'5b29018b55ba'
原因:该版本曾经upgrade执行过了,但是文件被删除,
解决办法:更新数据库 alembic_version 表记录
ERROR [alembic.util.messaging] Can't locate revision identified by 'a2de455a4f51' FAILED: Can't locate revision identified by 'a2de455a4f51'
执行 alembic autogenerate 没有看到生成的 py 文件有数据库更新操作的代码
原因:Base import 不正确,或者 model 定义不正确
解决办法:检查 model 代码
数据库还没有执行 upgrade head 更新,不能执行 autogenerate
ERROR [alembic.util.messaging] Target database is not up to date. FAILED: Target database is not up to date.
删除所有 py 文件之后的重新开始,最好把数据库的表也删除完
这样才能确保生成的py文件反应所有数据库变更
单独更改列名或一些列属性和表名等不能自动识别
需要注意