return render_template(‘login.html’);
登录页面是用Layui写的一组form表单,也是基础的base.html,代码如下:
{% extends ‘base.html’ %}
{% block title %}
在线博客平台.登录
{% endblock %}
{% block css %}
{% endblock %}
{% block content %}
登录
{% for item in get_flashed_messages() %}
{{ item }}
{% endfor %}
必看视频!获取2024年最新Java开发全套学习资料 备注Java
立即提交
重置
{% endblock %}
{% block login_class %}
layui-this
{% endblock %}
效果如下(账号和密码错误后,会有相应的提示信息):
注册和登录差不多,页面都是使用的同一个css样式文件,所以这里就贴代码出来了,需要的可以自行下载完整项目代码:GitHub地址。
修改密码
修改密码模块,因为数据库存放明文密码很不安全,所以这里使用了Werkzeug对密码进行了加密存储。对于WerkZeug密码加密想进一步了解的,可以访问[Flask 使用Werkzeug实现密码加密。
]( )
因为数据库中存储的是加密后的密码,所以这里判断原密码是否正确需要使用check_password_hash函数进行判断。
定义一个修改密码的视图函数。
修改密码
@index.route(“/updatePwd”, methods=[‘POST’, ‘GET’])
@login_limit
def update():
if request.method == “GET”:
return render_template(“updatePwd.html”)
if request.method == ‘POST’:
lodPwd = request.form.get(“lodPwd”)
newPwd1 = request.form.get(“newPwd1”)
newPwd2 = request.form.get(“newPwd2”)
username = session.get(“username”);
user = User.query.filter(User.username == username).first();
if check_password_hash(user.password, lodPwd):
if newPwd1 != newPwd2:
flash(“两次新密码不一致!”)
return render_template(“updatePwd.html”)
else:
user.password_hash(newPwd2)
db.session.commit();
flash(“修改成功!”)
return render_template(“updatePwd.html”)
else:
flash(“原密码错误!”)
return render_template(“updatePwd.html”)
页面样式文件和登录注册引入的样式文件一致(原密码不正确或两次新密码不同,会给出相应的提示信息),代码如下:
{% extends ‘base.html’ %}
{% block title %}
在线博客平台.修改密码
{% endblock %}
{% block css %}
{% endblock %}
{% block content %}
修改密码
{% for item in get_flashed_messages() %}
{{ item }}
{% endfor %}
立即提交
{% endblock %}
{% block updatepwd_class %}
layui-this
{% endblock %}
效果如下:
写博客
写博客,博客表中会保存标题、博客内容、当前时间等字段。如下是写博客的视图函数。
写博客页面
@blog.route(‘/writeBlog’, methods=[‘POST’, ‘GET’])
@login_limit
def writeblog():
if request.method == ‘GET’:
return render_template(‘writeBlog.html’)
if request.method == ‘POST’:
title = request.form.get(“title”)
text = request.form.get(“text”)
username = session.get(‘username’)
获取当前系统时间
create_time = time.strftime(“%Y-%m-%d %H:%M:%S”)
user = User.query.filter(User.username == username).first()
blog = Blog(title=title, text=text, create_time=create_time, user_id=user.id)
db.session.add(blog)
db.session.commit();
blog = Blog.query.filter(Blog.create_time == create_time).first();
return render_template(‘blogSuccess.html’, title=title, id=blog.id)
保存博客时会获取到当前系统时间,当做博客的发布时间。博客保存成功后,会返回保存成功页面,下面会有讲解。
写博客对应的html文件,代码如下。
{% extends ‘base.html’ %}
{% block title %}
在线博客平台.写博客
{% endblock %}
{% block css %}
{% endblock %}
{% block content %}
保存
{% endblock %}
{% block write_class %}
layui-this
{% endblock %}
写博客这里采用的是Markdown编辑器,对于Markdown编辑器之前写过一篇Markdown的使用方法,只不过后端用的是Java语言,感兴趣的小伙伴可以看看,Markdown的基本使用。Flask与之不同的是,后端接收Markdown上传图片时的语句不同,Flask接收Markdown上传图片的语句:
file = request.files.get(‘editormd-image-file’);
其他的基本相同,毕竟Markdown是属于前端的知识,后端只要求根据规定个格式返回数据即可。
因为Markdown支持图片上传,那就必须的有文件上传的方法了。如下定义一个文件上传的视图函数(这里需要注意的是Markdown上传图片是使用的POST方法)。
上传图片
@blog.route(‘/imgUpload’, methods=[‘POST’])
@login_limit
def imgUpload():
try:
file = request.files.get(‘editormd-image-file’);
fname = secure_filename(file.filename);
ext = fname.rsplit(‘.’)[-1];
生成一个uuid作为文件名
fileName = str(uuid.uuid4()) + “.” + ext;
filePath = os.path.join(“static/uploadImg/”, fileName);
file.save(filePath)
return {
‘success’: 1,
‘message’: ‘上传成功!’,
‘url’: “/” + filePath
}
except Exception:
return {
‘success’: 0,
‘message’: ‘上传失败’
}
如果对上述的文件上传代码比较陌生,可以访问Flask 文件上传与下载,对Flask文件上传与下载进一步了解。
效果如下:
保存成功后,会返回保存成功页面,可以在写一篇,或者查看当前发布的文章。
查看博客列表
查看博客列表就是遍历所有已发布的博客。先定义一个视图函数,查询所有已发布的博客,传递到前端进行遍历显示。视图函数代码如下:
展示全部博客
@blog.route(“/blogAll”)
def blogAll():
order_by按照时间倒序
blogList = Blog.query.order_by(Blog.create_time.desc()).all();
return render_template(‘blogAll.html’, blogList=blogList)
因为最新发布的博客在数据库的最后一条,所以这里根据发布时间倒序查询。
页面代码如下:
{% extends ‘base.html’ %}
{% block title %}
在线博客平台.博客
{% endblock %}
{% block css %}
{% endblock %}
{% block content %}
{% for blog in blogList %}
-
发布人:{{ blog.user.name }} 发布时间:{{ blog.create_time }}
{% endfor %}
{% endblock %}
{% block blog_class %}
layui-this
{% endblock %}
效果如下:
博客详情页面
在博客列表中点击博客的标题可以进入博客的详情页面,详情页面展示了博客的详细内容以及评论内容。
因为数据库中保存博客内容的是Markdown格式的,所以在这里需要解析成HTML格式,解析代码如下。
editormd.markdownToHTML(“test”, {
htmlDecode: “style,script,iframe”,
emoji: true,
taskList: true,
tex: true, // 默认不解析
flowChart: true, // 默认不解析
sequenceDiagram: true // 默认不解析
});
评论
在博客详情页面可以进行评论,评论使用的是Layui的编辑器,比较简约也可以达到想要的效果。效果如图。
看上去是不是还可以,和页面也很搭。评论需要先登录才可以评论,如果没有登录则会提示登录。
如果登录评论后,会发送保存评论请求,携带当前博客的id和评论内容进行保存。
保存评论的视图函数
评论
@blog.route(“/comment”, methods=[‘POST’])
@login_limit
def comment():
text = request.values.get(‘text’)
blogId = request.values.get(‘blogId’)
username = session.get(‘username’)
获取当前系统时间
create_time = time.strftime(“%Y-%m-%d %H:%M:%S”)
user = User.query.filter(User.username == username).first()
comment = Comment(text=text, create_time=create_time, blog_id=blogId, user_id=user.id)
db.session.add(comment)
db.session.commit();
return {
‘success’: True,
‘message’: ‘评论成功!’,
}
上述的博客内容解析与评论都在一个页面中,完整代码如下。
{% extends ‘base.html’ %}
{% block title %}
在线博客平台.博客
{% endblock %}
{% block css %}
{% endblock %}
{% block content %}
{{ blog.title }}
发布人:{{ blog.user.name }} 发布时间:{{ blog.create_time }}
提交评论
{% for com in comment %}
{{ com.text }}
评论人:{{ com.user.name }} 发布时间:{{ com.create_time }}
{% endfor %}
{% endblock %}
我的博客
登录之后在右上角导航栏可以查看我的博客,查看个人已经发布过的博客并进行管理。
定义一个视图函数,查询当前登录的用户发布的所有博客。
查看个人博客
@blog.route(“/myBlog”)
@login_limit
def myBlog():
username = session.get(‘username’)
user = User.query.filter(User.username == username).first()
order_by按照时间倒序
blogList = Blog.query.filter(Blog.user_id == user.id).order_by(Blog.create_time.desc()).all()
return render_template(“myBlog.html”, blogList=blogList)
页面与博客列表基本相似,但可以对其博客进行修改与删除。
修改博客
在我的博客中,有修改博客的链接,把当前的博客id当做参数传递到后台,查询当前这条博客的数据,进行修改。
博客修改
@blog.route(“/update/”, methods=[‘POST’, ‘GET’])
@login_limit
def update(id):
if request.method == ‘GET’:
blog = Blog.query.filter(Blog.id == id).first();
return render_template(‘updateBlog.html’, blog=blog)
if request.method == ‘POST’:
id = request.form.get(“id”)
title = request.form.get(“title”)
text = request.form.get(“text”)
blog = Blog.query.filter(Blog.id == id).first();
blog.title = title;
blog.text = text;
db.session.commit();
return render_template(‘blogSuccess.html’, title=title, id=id)
修改页面和写博客的页面基本一样,在textarea标签中设置markdown编辑器的默认值。
{{ blog.text }}删除博客
删除博客和修改一样,把博客的id传到后端,根据id删除数据库中对应的数据。
删除博客
@blog.route(“/delete/”)
@login_limit
def delete(id):
blog = Blog.query.filter(Blog.id == id).first();
db.session.delete(blog);
db.session.commit();
return {
‘state’: True,
‘msg’: “删除成功!”
}
删除成功后,使用JS删除页面上对应的DOM元素。
function del(url, that){
layui.use(‘layer’, function(){
var layer = layui.layer;
layer.confirm(‘您确定要删除吗?’, {
btn: [‘取消’,‘确定’]
}, function(index){
layer.close(index);
}, function(){
$.get(url, function (data){
if(data.state){
$(that).parent().parent().parent().remove();
layer.msg(data.msg, {icon: 1});
}
})
});
});
}
我的评论
在页面的右上角不仅可以查看个人已发布的博客,也可以看到自己的所有评论信息。
根据评论列表,可以点击评论或博客,可以进入评论的博客详情页中;也可以对评论的内容进行删除操作。
定义一个视图函数,查询所有的评论内容,返回给前台遍历展示(同样根据时间倒序查询)。
用户所有的评论
@blog.route(‘/myComment’)
@login_limit
def myComment():
username = session.get(‘username’)
user = User.query.filter(User.username == username).first()
order_by按照时间倒序
commentList = Comment.query.filter(Comment.user_id == user.id).order_by(Comment.create_time.desc()).all();
return render_template(“myComment.html”, commentList=commentList)
前端页面展示代码。
{% extends ‘base.html’ %}
{% block title %}
在线博客平台.我的评论
{% endblock %}
{% block css %}
{% endblock %}
{% block content %}
{% for comment in commentList %}
-
博客:{{ comment.blog.title }} 评论时间:{{ comment.create_time }}
删除
{% endfor %}
{% endblock %}
页面样式和博客列表样式一致。
删除评论
在评论列表中有删除评论的链接,根据评论的id删除当前条评论,删除后,对应博客中的评论也随之删除。
删除评论
最后
针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。
下面的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题(都整理成文档,小部分截图)
最新整理电子书
k %}
{% block content %}
{% for comment in commentList %}
-
博客:{{ comment.blog.title }} 评论时间:{{ comment.create_time }}
删除
{% endfor %}
{% endblock %}
页面样式和博客列表样式一致。
删除评论
在评论列表中有删除评论的链接,根据评论的id删除当前条评论,删除后,对应博客中的评论也随之删除。
删除评论
最后
针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。
下面的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题(都整理成文档,小部分截图)
[外链图片转存中…(img-sGN8yUa0-1716471289661)]
最新整理电子书
[外链图片转存中…(img-eODgTnbE-1716471289661)]