标签:post 密码加密 热门 rop 详情 reg _id 生成 就是
一、 系统概要说明
本系统是一个新浪资讯分享的网站,用户们可以利用自己的见解分享对时事的认知,发布不同类型的帖子,有娱乐八卦,汽车类博文,最热门的世界杯体育类资讯等等。用户与用户之间可以参与互动,对帖子进行点赞评论或者收藏,这是一个有言论自由、开放但安全性高的网站。
Flask是一个精简灵活的框架,python语言也是当前最流行、极高采用性高级语言,而sqlalcheny是flask的一个扩展,是一个关系型数据库的框架,将繁琐的数据库操作转化为python的类,通俗点说就是转化为sql语,对于初学者来说较为通俗易懂,不需花太多时间去钻研,很方便。这次我选用了pyvharm64软件作为开发工具。
二、 网站结构设计
网站的逻辑结构:网页链接的网络图
如下图:
网站的物理结构:网站的目录和文件存储的位置
如下图:
三、 模块详细设计
网站主要的功能模块有:用户的注册、登录和注销;详情页包括标题、内容和评论;发布、列表显示;个人中心;模糊搜索;评论、列表显示;点赞、收藏;资讯分类与显示;修改密码,头像显示;我的发布包括详情与评论、点赞、收藏;高级搜索;推荐作者、热门文章。
(1)用户
在未登录前只可以浏览其他网友的帖子,进行注册登陆个人账号后,能发布帖子,对其他的博客可以进行点赞、收藏和评论。还可以修改个人密码,但不能擅自改动其他用户的信息。
(2)资讯
资讯内容有多个方式显示,热门程度、时间和不同的类型。可以被用户浏览详情、并有点赞收藏和评论功能,可以在首页中查看评论浏览和点赞的数目,清晰可见。
(3)搜索
有模糊搜索和高级搜索,模糊搜索是通过用户昵称或咨询内容的关键字查询;高级搜索是按照内容的类型来查询相关资讯,只能浏览无法修改。
四、 数据库设计
本次博客系统中连接的数据库是Navicat·for`MySQL,在ip地址127.0.0.1中创建qingting数据库。
为了建立mysql与app的连接,在python中配置信息congif.py文件:
用户表:
class User(db.Model): # 创建类User __tablename__ = ‘user‘ # 类对应的表名user id = db.Column(db.Integer, primary_key=True, autoincrement=True) # autoincrement自增长 username = db.Column(db.String(20), nullable=False) # nullable是否为空 _password = db.Column(db.String(200), nullable=False) # 密码加密内部使用 nickname = db.Column(db.String(20), nullable=True)
评论表:
class Comment(db.Model): # 评论 __tablename__ = ‘comment‘ id = db.Column(db.Integer, primary_key=True, autoincrement=True) author_id = db.Column(db.Integer, db.ForeignKey(‘user.id‘)) publish_id = db.Column(db.Integer, db.ForeignKey(‘publish.id‘)) creat_time = db.Column(db.DateTime, default=datetime.now) detail = db.Column(db.Text, nullable=False) publish = db.relationship(‘publish‘,backref=db.backref(‘comments‘, order_by=creat_time.desc)) # order_by=creat_time.desc按时间降序 author = db.relationship(‘User‘, backref=db.backref(‘comments‘))
点赞表:
class Dianzang(db.Model): # 点赞 __tablename__ = ‘dianzang‘ id = db.Column(db.Integer, primary_key=True, autoincrement=True) author_id = db.Column(db.Integer, db.ForeignKey(‘user.id‘)) publish_id = db.Column(db.Integer, db.ForeignKey(‘publish.id‘)) publish = db.relationship(‘publish‘, backref=db.backref(‘dianzangs‘)) author = db.relationship(‘User‘, backref=db.backref(‘dianzangs‘))
发布表:
class publish(db.Model): # 问答 __tablename__ = ‘publish‘ id = db.Column(db.Integer, primary_key=True, autoincrement=True) title = db.Column(db.String(100), nullable=False) detail = db.Column(db.Text, nullable=False) leixing = db.Column(db.String(20), nullable=True) creat_time = db.Column(db.DateTime, default=datetime.now) # 提交时间会自己赋值 author_id = db.Column(db.Integer, db.ForeignKey(‘user.id‘)) # 数据类型是db.Integer,db.ForeignKey参数指定外键是哪个表中哪个id author = db.relationship(‘User‘, backref=db.backref(‘publish‘)) # 建立关联,其author属性将返回与问答相关联的用户实例,相当于数据库中的表连接 # 第一个参数表明这个关系的另一端是哪个类,第二个参数backref,将向User类中添加一个publish属性,从而定义反向关系,这一属性可访问publish类,获取的是模型对象 yuedu = db.Column(db.Integer, nullable=False)
收藏表:
class Shoucang(db.Model): # 收藏 __tablename__ = ‘shoucang‘ id = db.Column(db.Integer, primary_key=True, autoincrement=True) author_id = db.Column(db.Integer, db.ForeignKey(‘user.id‘)) publish_id = db.Column(db.Integer, db.ForeignKey(‘publish.id‘)) publish = db.relationship(‘publish‘, backref=db.backref(‘shoucangs‘)) author = db.relationship(‘User‘, backref=db.backref(‘shoucangs‘))
五、 系统实现的关键算法与数据结构
5.1登录、注册、注销
#登录功能 @app.route(‘/login/‘, methods=[‘GET‘, ‘POST‘]) # methods定义它有两种请求方式 def login(): if request.method == ‘GET‘: return render_template(‘login.html‘) else: username = request.form.get(‘user‘) # post请求模式,安排对象接收数据 password = request.form.get(‘pass‘) user = User.query.filter(User.username == username).first() # 作查询,并判断 if user: # 判断用户名 if user.check_password(password): # 判断密码 session[‘user‘] = username # 利用session添加传回来的值username session[‘user_id‘] = user.id session.permanent = True # 设置session过期的时间 return redirect(url_for(‘index‘)) else: return u‘用户密码错误‘ else: return u‘用户不存在,请先注册‘
#注册功能 @app.route(‘/regist/‘, methods=[‘GET‘, ‘POST‘]) # methods定义它有两种请求方式,因为它在表单的请求是post,类似我们在idea中的sava请求模式 def regist(): if request.method == ‘GET‘: return render_template(‘regist.html‘) else: username = request.form.get(‘user‘) # post请求模式,安排对象接收数据 password = request.form.get(‘pass‘) nickname = request.form.get(‘nickname‘) user = User.query.filter(User.username == username).first() # 作查询,并判断 if user: return u‘该用户已存在‘ else: user = User(username=username, password=password, nickname=nickname) # 将对象接收的数据赋到User类中,即存到数据库 db.session.add(user) # 执行操作 db.session.commit() return redirect(url_for(‘login‘)) # redirect重定向
# 注销功能 @app.route(‘/logout‘) def logout(): session.clear() # 注销时删除所有session return redirect(url_for(‘index‘))
5.2个人中心
# 个人中心 @app.route(‘/yonghu/<username_id>/<tag>‘) # 为了把页面分开,我们在html页面传了一个tag参数 def yonghu(username_id, tag): user = User.query.filter(User.id == username_id).first() shoucang = Shoucang.query.filter(Shoucang.author_id == username_id).all() context = { ‘userid‘: user.id, ‘username‘: user.username, ‘nickname‘: user.nickname, ‘publishs‘: user.publish, ‘comments‘: user.comments, ‘shoucang‘: shoucang } # 根据tag的不同去到不同页面,一个请求跳转3个不同页面 if tag == ‘1‘: return render_template(‘usercenter1.html‘, **context) elif tag == ‘2‘: return render_template(‘usercenter2.html‘, **context) elif tag == ‘3‘: return render_template(‘usercenter3.html‘, **context) else: return render_template(‘usercenter4.html‘, **context)
5.3搜索
#搜索功能 @app.route(‘/search/‘) def search(): sousuo = request.args.get(‘sousuo‘) # args获取关键字,区别form author = User.query.all() ydpublish = publish.query.filter(publish.yuedu > 5).all() publishs = publish.query.filter( or_( # 两种查询条件 publish.title.contains(sousuo), # contains模糊查 publish.detail.contains(sousuo) ) ).order_by(‘-creat_time‘) return render_template(‘index.html‘, publishs=publishs, author=author, ydpublish=ydpublish) # publishs要和原首页数据模型一样
5.3文章分类
# 分类查询 @app.route(‘/fenlei/‘) def fenlei(): fenlei = request.args.get(‘fenlei‘) # args获取关键字,区别form author = User.query.all() ydpublish = publish.query.filter(publish.yuedu > 5).all() fenlei_publishs = publish.query.filter( or_( # 两种查询条件 # publish.creat_time.contains(fenlei), publish.leixing.contains(fenlei), # contains模糊查 # publish.title.contains(fenlei) ) ).order_by(‘-creat_time‘) return render_template(‘index.html‘, publishs=fenlei_publishs, author=author, ydpublish=ydpublish) # publishs要和原首页数据模型一样
5.4点赞
#点赞功能 @app.route(‘/dianzang/‘, methods=[‘POST‘]) @loginFirst def dianzang(): dzpublish_id = request.form.get(‘dzpublish_id‘) dzuser_id = request.form.get(‘dzuser_id‘) dianzang = Dianzang(publish_id=dzpublish_id, author_id=dzuser_id) db.session.add(dianzang) # 执行操作 db.session.commit() # 提交到数据库 return redirect(url_for(‘publishview‘, fabu_id=dz.fabu_id))
5.5收藏
#收藏功能 @app.route(‘/shoucang/‘, methods=[‘POST‘]) @loginFirst def shoucang(): scpublish_id = request.form.get(‘scpublish_id‘) scuser_id = request.form.get(‘scuser_id‘) shoucang = Shoucang(publish_id=scpublish_id, author_id=scuser_id) db.session.add(shoucang) # 执行操作 db.session.commit() # 提交到数据库 return redirect(url_for(‘publishview‘, publish_id=scpublish_id))
5.6发布帖子、评论
# 发布内容功能 @app.route(‘/publish/‘, methods=[‘GET‘, ‘POST‘]) # methods定义它有两种请求方式 @loginFirst # 将decorator定义的增强函数放在待增强函数定义的上面 def publish(): if request.method == ‘GET‘: return render_template(‘publish.html‘) else: title = request.form.get(‘title‘) # post请求模式,安排对象接收数据 detail = request.form.get(‘detail‘) leixing = request.form.get(‘leixing‘) yuedu = 0 author_id = User.query.filter( User.username == session.get(‘user‘)).first().id # 将session get到的user进行查询并取出id放到外键author_id中 publish = publish(title=title, detail=detail, author_id=author_id, leixing=leixing, yuedu=yuedu) # 将对象接收的数据赋到publish类中,即存到数据库 db.session.add(publish) # 执行操作 db.session.commit() # 提交到数据库 return redirect(url_for(‘index‘)) # redirect重定向
#发布评论 @app.route(‘/comment/‘, methods=[‘POST‘]) @loginFirst # 装饰器,跳转某页面之前先进行登录 def comment(): detail = request.form.get(‘pinglun‘) # post请求模式,安排对象接收数据 author_id = User.query.filter(User.username == session.get(‘user‘)).first().id publish_id = request.form.get(‘fa_id‘) comment = Comment(detail=detail, author_id=author_id, publish_id=publish_id) # 将对象接收的数据赋到Comment类中,即存到数据库 db.session.add(comment) # 执行操作 db.session.commit() # 提交到数据库 return redirect(url_for(‘publishview‘, publish_id=publish_id)) # 重定向到publishview请求时要带publish_id
5.7修改密码
#修改密码功能 @app.route(‘/password_update/<user_id>‘) def password_update(user_id): users = User.query.filter(User.id == user_id).first() # 查询出要修改密码的该用户 return render_template(‘password_update.html‘, users=users) # 修改密码后接受数据 @app.route(‘/password_update1/‘, methods=[‘POST‘]) def password_update1(): username = request.form.get(‘username‘) # 接收username的值,知道要修改的是哪个用户 password1 = request.form.get(‘password1‘) password2 = request.form.get(‘password2‘) users = User.query.filter(User.username == username).first() # 查询出要修改用户的整条信息 users.password1 = password1 # 执行修改 users.password2 = password2 db.session.commit() return redirect(url_for(‘yonghu‘, username_id=users.id, tag=‘1‘))
5.8排序算法
通过查询时间、热度(浏览次数)来对用户发布帖子的展示进行排序。
@app.route(‘/‘) def index(): pl = request.args.get(‘pl‘) # 接收顺序排列的关键词,接收不到就按时间排列 if pl == ‘按热度‘: context = { ‘publishs‘: publish.query.order_by(‘-yuedu‘).all(), ‘author‘: User.query.all(), ‘ydpublish‘: publish.query.filter(publish.yuedu > 5).all() # 当发布的文章阅读量大于多少时取出这些文章,显示在首页的推荐文章 } return render_template(‘index.html‘, **context) else: context = { ‘publishs‘: publish.query.order_by(‘-creat_time‘).all(), ‘author‘: User.query.all(), ‘ydpublish‘: publish.query.filter(publish.yuedu > 5).all() # 当发布的文章阅读量大于多少时取出这些文章,显示在首页的推荐文章 } return render_template(‘index.html‘, **context)
5.9加密算法
设置用户密码的时候分成内部使用和外部使用两种,内部使用的密码是管理员打开数据库也看不到的,只有用户知道自己设置的密码,从而提高了用户的账户安全性。
class User(db.Model): # 创建类User __tablename__ = ‘user‘ # 类对应的表名user id = db.Column(db.Integer, primary_key=True, autoincrement=True) # autoincrement自增长 username = db.Column(db.String(20), nullable=False) # nullable是否为空 _password = db.Column(db.String(200), nullable=False) # 密码加密内部使用 nickname = db.Column(db.String(20), nullable=True) @property # 定义函数,需要用属性时可以用函数代替 def password(self): # 密码加密外部使用 return self._password @password.setter def password(self, row_password): # 密码进来时进行加密,generate_password_hash是一个密码加盐哈希函数,生成的哈希值可通过check_password_hash()进行验证。 self._password = generate_password_hash(row_password) def check_password(self, row_password): # check_password_hash函数用于验证经过generate_password_hash哈希的密码。若密码匹配,则返回真,否则返回假。 result = check_password_hash(self._password, row_password) return result
六、 成品展示
6.1首页
6.2发布页
6.3修改密码页
6.4个人信息页
6.5发布信息页
6.6评论信息页
6.7收藏文章页
6.8登录页
6.9注册页
标签:post 密码加密 热门 rop 详情 reg _id 生成 就是
原文地址:https://www.cnblogs.com/qingting/p/9189698.html