博客管理系统
实战需求
项目目录结果
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 管理数据