tornado用户系统

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>&nbsp;码:<input type="password" placeholder="请输入密码" name="password"><br>&nbsp;码:<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>&nbsp;码:<input type="password" placeholder="请输入密码" name="password"><br>
    <button type="submit">登录</button>

    </form>
{% end %}

 

posted @ 2020-05-24 22:16  不会飞的鲨鱼  阅读(293)  评论(0)    收藏  举报