项目 04 数据库迁移工具
#1、安装一个版本迁移 pip install alembic #2、初始化目录 alembic init alembic #3、在alembic.ini文件第38行写入数据库地址 #4、在env.py中修改1-12行和25行 #5、创建一个models的account.py文件 #6、输出操作命令 alembic revision --autogenerate -m 'add fields for user' #7、刷入数据库 alembic upgrade head
#关于输出命令 alembic revison --autogenerate -m 'add post model' #添加post表 alembic downgrade -1 #回退一个版本
handles/main.py 更新
import tornado.web import os from pycket.session import SessionMixin from utils import photo from utils.account import add_post_for,get_post_for class AuthBaseHandler(tornado.web.RequestHandler,SessionMixin): def get_current_user(self): return self.session.get('tudo_user_info') class IndexHandler(AuthBaseHandler): """ Home page for user,photo feeds """ @tornado.web.authenticated def get(self,*arg,**kwargs): posts = get_post_for(self.current_user) image_urls = [p.image_url for p in posts] self.render('index.html',images = image_urls) class ExploreHandler(AuthBaseHandler): """ Explore page,photo of other users """ def get(self,*arg,**kwargs): posts = get_post_for(self.current_user) thumb_urls = [p.thumb_url for p in posts]#拿到缩略图的url self.render('explore.html',images=thumb_urls)#打开explore文件并将图片放上去 class PostHandler(tornado.web.RequestHandler): """ Single photo page and maybe """ def get(self,*arg,**kwargs): self.render('post.html',post_id = kwargs['post_id']) class UploadHandler(AuthBaseHandler): """ 接收图片上传 """ def get(self,*arg,**kwargs): self.render('upload.html') def post(self, *args, **kwargs): img_files = self.request.files.get('newimg',None) for img in img_files: image_url = 'uploads/'+img['filename']#image的本地目录 save_to = os.path.join(self.settings['static_path'],image_url)#保存路径为虚拟机路径加本地目录 print("save_to {}".format(save_to)) with open(save_to,'wb') as f:#打开本地目录的图片文件 f.write(img['body'])#保存文件内容 full_path = photo.make_thumb(save_to) thumb_url = os.path.relpath(full_path,self.settings['static_path'])#相当于full_path减去settings['static_path'] add_post_for(self.current_user,image_url,thumb_url)#获取用户登录信息中的username self.write({'filename':img_files[0]['filename']}) self.redirect('/explore')
models/account.py 更新
''' 专门储存数据库的文件 ''' from datetime import datetime from sqlalchemy import (Column,Integer,String,DateTime, ForeignKey) from sqlalchemy.sql import exists from sqlalchemy.orm import relationship from .db import Base,DBSession session = DBSession() class User(Base): __tablename__ = 'users' id = Column(Integer,primary_key=True,autoincrement=True) name = Column(String(50),unique=True,nullable=False) password = Column(String(50),nullable=False) created = Column(DateTime,default=datetime.now) email = Column(String(50)) last_login = Column(DateTime) def __repr__(self): return '<User(#{}:{})>'.format(self.id,self.name) @classmethod def is_exists(cls,username):#判断用户名是否存在 return session.query(exists().where(User.name==username)).scalar() @classmethod def add_user(cls,username, password, email=''):#添加用户函数 user = User(name=username,password=password, email=email, last_login=datetime.now()) session.add(user) #初始化实例 session.commit() #刷入 @classmethod def get_pass(cls,username): #获取数据库用户的密码函数 user = session.query(cls).filter_by(name=username).first() #通过数据库查询获取用户密码 if user: return user.password #获取用户密码 else: return '' class Post(Base): ''' 保存用户图片信息 ''' __tablename__ = 'posts' id = Column(Integer,primary_key=True,autoincrement=True) image_url = Column(String(80)) thumb_url = Column(String(80)) user_id = Column(Integer,ForeignKey('users.id')) user = relationship('User',backref = 'posts',uselist = False,cascade = 'all')# user是User的一个实例 def __repr__(self): return "<Post(#{})>".format(self.id) if __name__=='__main__': Base.metadata.create_all()
utils/account.py
''' 用户相关的函数 ''' import hashlib#系统自带的加密库 hash加密 from models.account import User,session,Post from datetime import datetime def hash_it(password):#密码加密函数 return hashlib.md5(password.encode('utf8')).hexdigest() def authenticate(username,password): ''' 用户密码匹配判断函数,认证 :param username: :param password: :return: ''' if username and password: hash_pass = User.get_pass(username)# 获取数据库密码 if hash_pass and hash_it(password) == hash_pass:#将用户输入的密码和数据库密码两两配对是否相同 return True return False def login(username):#记录登录时间函数,用于记录用户每次登录的时间 t = datetime.now() print("user:{} login at {}".format(username,t)) session.query(User).filter_by(name=username).update({User.last_login:t})#在数据库里面添加登录记录 session.commit()#输入 def register(username,password,email): ''' 提交数据到数据库 :param username: :param password: :param email: :return: ''' if User.is_exists(username): return {'msg':'用户名已存在'} hash_pass = hash_it(password)#加密 User.add_user(username,hash_pass,email) return {'msg':'ok'} def add_post_for(username,image_url,thumb_url):#将路径保存到数据库 ''' 保存特定用户的图片 :param username: :return: ''' user = session.query(User).filter_by(name=username).first()#拿到user post = Post(image_url=image_url,thumb_url=thumb_url,user=user) session.add(post) session.commit() # return post.id def get_post_for(username): ''' 查看用户图片 :param username: :return: ''' user = session.query(User).filter_by(name=username).first() posts = session.query(Post).filter_by(user=user) #返回的是实例的对象 return posts