2024年Java最新Flask实现个人博客系统(附源码),java框架面试题springboot

本文档详细介绍了Java架构进阶面试的关键知识点,涵盖了集合、并发编程、JVM、分布式技术(如Dubbo、Redis、微服务架构等)、数据库设计(MySQL、分库分表等)和相关技术的面试问题解析。还包含了登录注册功能、Markdown编辑器应用和项目源码链接。
摘要由CSDN通过智能技术生成

最后

Java架构进阶面试及知识点文档笔记

这份文档共498页,其中包括Java集合,并发编程,JVM,Dubbo,Redis,Spring全家桶,MySQL,Kafka等面试解析及知识点整理

image

Java分布式高级面试问题解析文档

其中都是包括分布式的面试问题解析,内容有分布式消息队列,Redis缓存,分库分表,微服务架构,分布式高可用,读写分离等等!

image

互联网Java程序员面试必备问题解析及文档学习笔记

image

Java架构进阶视频解析合集

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 查看博客列表:查看所有已发布的博客

  • 博客详情页:查看博客内容及评论信息,可以对当前博客进行评论

  • 关于

项目目录


在这里插入图片描述

数据库设计


数据库一共设计了三张表:用户表、博客表、评论表。

表之间的映射关系如下:

在这里插入图片描述

用户表和博客表一对多关系;用户和评论表一对多关系;博客表和评论表一对多关系。

其表的模型类代码如下:

class User(db.Model):

设置表名

tablename = ‘tb_user’;

id,主键并自动递增

id = db.Column(db.Integer, primary_key=True, autoincrement=True)

username = db.Column(db.String(64), unique=True)

password = db.Column(db.String(256), nullable=True)

name = db.Column(db.String(64))

设置只可写入,对密码进行加密

def password_hash(self, password):

self.password = generate_password_hash(password);

class Blog(db.Model):

tablename = ‘blog’

id = db.Column(db.Integer, primary_key=True, autoincrement=True)

title = db.Column(db.String(128))

text = db.Column(db.TEXT)

create_time = db.Column(db.String(64))

#关联用户id

user_id = db.Column(db.Integer, db.ForeignKey(‘tb_user.id’))

user = db.relationship(‘User’, backref=‘user’)

class Comment(db.Model):

tablename = ‘comment’

id = db.Column(db.Integer, primary_key=True, autoincrement=True)

text = db.Column(db.String(256)) # 评论内容

create_time = db.Column(db.String(64))

关联博客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的编辑器,比较简约也可以达到想要的效果。效果如图。

        在这里插入图片描述

        看上去是不是还可以,和页面也很搭。评论需要先登录才可以评论,如果没有登录则会提示登录。

        在这里插入图片描述

        如果登录评论后,会发送保存评论请求,携带当前博客的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 %}

        感受:

        其实我投简历的时候,都不太敢投递阿里。因为在阿里一面前已经过了字节的三次面试,投阿里的简历一直没被捞,所以以为简历就挂了。

        特别感谢一面的面试官捞了我,给了我机会,同时也认可我的努力和态度。对比我的面经和其他大佬的面经,自己真的是运气好。别人8成实力,我可能8成运气。所以对我而言,我要继续加倍努力,弥补自己技术上的不足,以及与科班大佬们基础上的差距。希望自己能继续保持学习的热情,继续努力走下去。

        也祝愿各位同学,都能找到自己心动的offer。

        分享我在这次面试前所做的准备(刷题复习资料以及一些大佬们的学习笔记和学习路线),都已经整理成了电子文档

        拿到字节跳动offer后,简历被阿里捞了起来,二面迎来了P9"盘问"

        本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

        需要这份系统化的资料的朋友,可以点击这里获取

        %}

        {% block css %}

        {% endblock %}

        {% block content %}

        感受:

        其实我投简历的时候,都不太敢投递阿里。因为在阿里一面前已经过了字节的三次面试,投阿里的简历一直没被捞,所以以为简历就挂了。

        特别感谢一面的面试官捞了我,给了我机会,同时也认可我的努力和态度。对比我的面经和其他大佬的面经,自己真的是运气好。别人8成实力,我可能8成运气。所以对我而言,我要继续加倍努力,弥补自己技术上的不足,以及与科班大佬们基础上的差距。希望自己能继续保持学习的热情,继续努力走下去。

        也祝愿各位同学,都能找到自己心动的offer。

        分享我在这次面试前所做的准备(刷题复习资料以及一些大佬们的学习笔记和学习路线),都已经整理成了电子文档

        [外链图片转存中…(img-KsGtqjXL-1714907422532)]

        本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

        需要这份系统化的资料的朋友,可以点击这里获取

      • 8
        点赞
      • 16
        收藏
        觉得还不错? 一键收藏
      • 0
        评论

      “相关推荐”对你有帮助么?

      • 非常没帮助
      • 没帮助
      • 一般
      • 有帮助
      • 非常有帮助
      提交
      评论
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

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

      抵扣说明:

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

      余额充值