Flask实现个人博客系统(附源码)

关联博客id

blog_id = db.Column(db.Integer, db.ForeignKey(“blog.id”))

关联用户id

user_id = db.Column(db.Integer, db.ForeignKey(“tb_user.id”))

blog = db.relationship(“Blog”, backref=“blog”)

user = db.relationship(“User”, backref=“use”)

功能实现


页面基本模板实现

页面使用的是Jinja2模板,Jinja2支持页面继承,所以导航栏重复性的页面代码,我们都可以写在一个文件中。这里我们先创建一个base.html文件,编写页面大致的框架。其他模块直接继承使用即可。

{% block title %}

{# 其他页面可以重写标题 #}

{% endblock %}

{% block css %}

{% endblock %}

    • 在线博客平台
    • {% if username %}

    • 修改密码
    • {% endif %}

    • 博客
    • 关于
    • {% if username %}

    • {{ name }}

      我的博客
      我的评论
      注销
    • 写博客
    • {% else %}

    • 注册
    • {% endif %}

      {% block content %}

      {# 其他页面内容 #}

      {% endblock %}

      这里页面使用了Layui定义了一个导航栏,展示了对应的功能模块。其中{% if username %},username为后台存放在session中的一个键值对,用于判断用户是否登录了,有些功能登录后才显示。

      base.html模板文件完成后,我们在定义一个index.html来做项目的首页,直接继承base.html。这样首页index.html就节省了很多代码。如下:

      {% extends ‘base.html’ %}

      {% block title %}

      在线博客平台

      {% endblock %}

      {% block content %}

      在线博客平台

      {% endblock %}

      首页效果如下:

      登录与注册功能

      登录

      先定义一个登录的视图函数,可以接收GET、POST请求,GET请求为跳转到登录页面,POST请求为处理登录提交的请求,验证是否登录成功,登录成功后把当前登录对象的用户名存入session会话中。

      登录请求

      @index.route(‘/login’, methods=[‘POST’, ‘GET’])

      def login():

      if request.method == ‘GET’:

      return render_template(‘login.html’)

      if request.method == ‘POST’:

      username = request.form.get(‘username’)

      password = request.form.get(‘password’)

      user = User.query.filter(User.username == username).first();

      check_password_hash比较两个密码是否相同

      if (user is not None) and (check_password_hash(user.password, password)):

      session[‘username’] = user.username

      session.permanent = True

      return redirect(url_for(‘index.hello’))

      else:

      flash(“账号或密码错误”)

      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 %}

      立即提交

      重置

      {% 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.title }}

        发布人:{{ 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的编辑器,比较简约也可以达到想要的效果。效果如图。

      评论
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

      当前余额3.43前往充值 >
      需支付:10.00
      成就一亿技术人!
      领取后你会自动成为博主和红包主的粉丝 规则
      hope_wisdom
      发出的红包
      实付
      使用余额支付
      点击重新获取
      扫码支付
      钱包余额 0

      抵扣说明:

      1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
      2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

      余额充值