Skip to content

博客管理系统

实战需求

点击查看实战详情

项目目录结果

flask_blog/
│
├── app.py                     # 主程序入口
├── static/                    # 静态文件   └── css/
│       └── style.css          # 自定义 CSS 文件
└── templates/                 # 模板文件
    ├── base.html              # 公共模板
    ├── index.html             # 首页模板
    ├── blogs.html             # 博客列表模板
    └── blog_detail.html       # 博客详情模板

实现代码

1. 数据库准备

from sqlalchemy import create_engine, Column, Integer, String, text, Text
from sqlalchemy.orm import declarative_base, sessionmaker, Session

# 声明基类
Base = declarative_base()
# 创建引擎,连接到数据库
engine = create_engine(f'mysql+pymysql://{username}:{pwd}@{ip}:{port}/{database}')
# 创建session对象,绑定到数据库引擎上
DBSession = sessionmaker(bind=engine)
db_session: Session = DBSession()


class Blogs(Base):

    # 设置数据库表名
    __tablename__ = "blogs"

    id = Column(Integer, primary_key=True, autoincrement=True)
    title = Column(String(200), nullable=False)
    content = Column(Text, nullable=False)

    def __repr__(self):
        return f'<Blog {self.title}>'

    def to_dict(self):
        """将模型转换为字典格式"""
        return {
            "id": self.id,
            "title": self.title,
            "content": self.content
        }



if __name__ == "__main__":
    # 创建表
    Base.metadata.create_all(engine)
    blog1 = Blogs(
        id=1,
        title="flask环境安装与配置",
        content="Flask 是一个轻量级的 Web 开发框架。它是依赖 Jinja2 和 Werkzeug WSGI 服务的一个微型框架。"
    )
    blog2 = Blogs(
        id=2,
        title="接口路由技术",
        content="路由是将 URL 地址与应用程序中的函数相映射的过程。当用户在浏览器中输入特定的 URL 地址时,Flask 会调用与该地址相匹配的函数并返回相应的结果。"
    )
    blog3 = Blogs(
        id=3,
        title="处理响应信息",
        content="响应信息可以响应很多类型的信息类型。常见的比如文本类型,还有非常通用的 JSON 数据。"
    )
    db_session.add_all([blog1, blog2, blog3])
    # 将数据提交到commit
    db_session.commit()
    # 关闭连接
    db_session.close()

2. 主程序入口:app.py

from flask import Flask, abort, render_template, jsonify
from flask_cors import CORS
from flask_bootstrap import Bootstrap
from flask import Blueprint
from sqlalchemy import create_engine, Column, Integer, String, text, Text
from sqlalchemy.orm import declarative_base, sessionmaker, Session

# 声明基类
Base = declarative_base()
# 创建引擎,连接到数据库
username = "root"
pwd = "hogwarts"
ip = "127.0.0.1"
port = 3306
database = "flask_prac"
engine = create_engine(f'mysql+pymysql://{username}:{pwd}@{ip}:{port}/{database}')
# 创建session对象,绑定到数据库引擎上
DBSession = sessionmaker(bind=engine)
db_session: Session = DBSession()


class Blogs(Base):

    # 设置数据库表名
    __tablename__ = "blogs"

    id = Column(Integer, primary_key=True, autoincrement=True)
    title = Column(String(200), nullable=False)
    content = Column(Text, nullable=False)

    def __repr__(self):
        return f'<Blog {self.title}>'

    def to_dict(self):
        """将模型转换为字典格式"""
        return {
            "id": self.id,
            "title": self.title,
            "content": self.content
        }

# 关闭连接
db_session.close()

app = Flask(__name__)
# 启用跨域支持
CORS(app)
# 启用 Bootstrap 插件
Bootstrap(app)

# 定义蓝图
blog_blueprint = Blueprint(
    "blogs", __name__,
    template_folder="templates",
    static_folder="static"
)



# 首页路由
@app.route("/")
def index():
    # 返沪首页 html
    return render_template("index.html")


# 博客列表路由
@blog_blueprint.route("/")
def blog_list():
    # 查询数据库获取全部课程列表
    blogs = db_session.query(Blogs).all()
    # 返回博客列表页面 html 与博客数据
    return render_template("blogs.html", blogs=blogs)


# 博客详情路由
@blog_blueprint.route("/<int:id>")
def blog_detail(id):
    # 查询数据库获取全部课程列表
    blogs = db_session.query(Blogs).all()
    # 使用列表推导式获取全部数据列表,列表中元素为每个查询结果的字典格式
    blog_datas = [b.to_dict() for b in blogs]
    blog = None
    # 循环博客列表
    for b in blog_datas:
        # 如果路由中的 id 是某个博客对象的 id
        if id == b["id"]:
            # 查询到需要的博客
            blog = b
    # 如果路由中的 id 对应没有找到对应的博客
    if blog is None:
        # 返回错误提示信息
        return jsonify({
            "errcode": -1,
            "errmsg": "Blog not found",
        }), 404
    return render_template("blog_detail.html", blog=blog)


if __name__ == "__main__":
    # # 创建表
    # Base.metadata.create_all(engine)
    # blog1 = Blogs(
    #     id=1,
    #     title="flask环境安装与配置",
    #     content="Flask 是一个轻量级的 Web 开发框架。它是依赖 Jinja2 和 Werkzeug WSGI 服务的一个微型框架。"
    # )
    # blog2 = Blogs(
    #     id=2,
    #     title="接口路由技术",
    #     content="路由是将 URL 地址与应用程序中的函数相映射的过程。当用户在浏览器中输入特定的 URL 地址时,Flask 会调用与该地址相匹配的函数并返回相应的结果。"
    # )
    # blog3 = Blogs(
    #     id=3,
    #     title="处理响应信息",
    #     content="响应信息可以响应很多类型的信息类型。常见的比如文本类型,还有非常通用的 JSON 数据。"
    # )
    # db_session.add_all([blog1, blog2, blog3])
    # # 将数据提交到commit
    # db_session.commit()
    # # 关闭连接
    # db_session.close()
    # 注册蓝图
    app.register_blueprint(blog_blueprint, url_prefix="/blogs")
    # 启动应用
    app.run(host="0.0.0.0", port=5010, debug=True)

3. 自定义 CSS 文件:static/css/style.css

body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
}
header {
    background-color: #007bff;
    color: #fff;
    padding: 10px 20px;
}
nav a {
    margin-right: 10px;
    color: #fff;
    text-decoration: none;
}
main {
    padding: 20px;
}

4. 公共模板:templates/base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>博客管理系统</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
    <header>
        <h1>博客管理系统</h1>
        <nav>
            <a href="{{ url_for('index') }}">首页</a>
            <a href="{{ url_for('blogs.blog_list') }}">博客</a>
        </nav>
    </header>
    <main>
        {% block content %}{% endblock %}
    </main>
</body>
</html>

5. 首页模板:templates/index.html

{% extends "base.html" %}

{% block content %}
<h2>欢迎来到博客管理系统</h2>
<p>访问博客请从<a href="{{ url_for('blogs.blog_list') }}">这里</a>开始。</p>
{% endblock %}

6. 博客列表模板:templates/blogs.html

{% extends "base.html" %}

{% block content %}
<h2>博客列表</h2>
<ul>
    {% for blog in blogs %}
    <li><a href="{{ url_for('blogs.blog_detail', id=blog.id) }}">{{ blog.title }}</a></li>
    {% endfor %}
</ul>
{% endblock %}

7. 博客详情模板:templates/blog_detail.html

{% extends "base.html" %}

{% block content %}
<h2>{{ blog.title }}</h2>
<p>{{ blog.content }}</p>
<a href="{{ url_for('blogs.blog_list') }}">返回博客列表</a>
{% endblock %}

总结

  • 蓝图
  • 模版技术
  • 静态文件
  • ORM 管理数据