

创建后项目如下图

static存放静态文件,templates存放Jinja2模板,app.py是整个项目的入口文件
我们略微理解下app.py这里的代码
# 从flask这个包中导入Flask类
from flask import Flask
#使用Flask类创建一个app对象
#__name__:代表当前这个app.py模板
#1.以后出现bug,可以帮助我们快速定位
#2.对于寻找模板文件,有一个相对路径
app = Flask(__name__)
#创建一个路由和视图函数的映射
#https://www.baidu.com
#/home/user/。。。。
#这里单独一个/表示根路由
@app.route('/')
def hello_world(): # put application's code here
return 'Hello World!'
if __name__ == '__main__':
app.run()
我们运行代码

进入网站查看



说明:
debug模式
修改host
修改端口号
from flask import Flask
app = Flask(__name__)
# url:http[80]/https[443]//www.baidu.com:443/path
#url与视图:其实可以理解为path与视图
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route('/demo')
def china():
return 'Hello 中国'
if __name__ == '__main__':
app.run()
注意修改两个地方,一个是路径名,一个是函数名

带参数的url,将参数固定到了path中
@app.route('/demo2/' )
def demo2(id):
return '您携带的id是%s' % id

如果去掉int:,则传入什么都行,加入后只能传入int类型,否则会报错
用这种方式需要用到request,先在开头引入
from flask import Flask,request
#/book/list:会给我返回第一页的数据
#/book/list?page=2:获取第二页的数据
@app.route('/book/list')
def book_list():
#arguments:参数
#request.args:类字典类型
page = request.args.get("page",default=1,type=int)
return f"你得到的是第{page}的信息"


现在template里新建html文件


在body里填入内容就可以显示在页面上
比如在body里写个你好,运行代码

那么我们如何把页面渲染给前端,用render_template
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/')
def hello_world(): # put application's code here
# return 'Hello World!'
return render_template("index.html")
if __name__ == '__main__':
app.run()

如何给html传参使用


通过类传入数据
# app.py
class User:
def __init__(self,username,email):
self.username = username
self.email = email
@app.route('/')
def hello_world():
user=User(username="李四",email="123@qq.com")
person={
"username":"张三",
"email":"456@qq.com"
}
return render_template("index.html",user=user,person=person)
#index.html
<body>
这是传入的名字:{{ user.username }}
这是传入的邮箱:{{ user.email }}
<br>
{{ person['username'] }}
{{ person.username }}
{{ person['email'] }}
{{ person.email }}
</body>

通过管道符号|
我们在下例中写了两种形式,一种是用现有的比如length,还有一种是我们自定义的,比如这里的dformat
#app.py
def datetime_format(value,format="%Y年%m月%d日 %H时%M分%S秒"):
return value.strftime(format)
app.add_template_filter(datetime_format,"dformat")
@app.route('/filter')
def filter():
user=User(username="filter",email="123@qq.com")
mytime=datetime.now()
return render_template("filter.html",user=user,mytime=mytime)
#filter.html
<body>
{{ user.username }}--{{ user.username|length }}
<br>
{{ mytime }}--{{ mytime|dformat }}
</body>

(注:由于使用了datetime,在一开始要通过from datetime import datetime引入)
#app.py
@app.route("/control")
def control_statement():
age=10
book=[{
"name":"红楼梦",
"author":"曹雪芹",
},{
"name":"西游记",
"author":"吴承恩",
}]
return render_template("control.html",age=age,book=book)
#control.html
<body>
{% if age>18 %}
<div>你大于18岁</div>
{% elif age==18 %}
<div>你等于18岁</div>
{% else %}
<div>你小于18岁</div>
{% endif %}
{% for a in book %}
<div>name:{{ a.name }},author:{{ a.author }}</div>
{% endfor %}
</body>

#app.py
@app.route("/son")
def son():
return render_template("children.html")
#father.html
<body>
我是父亲的内容
{% block body %}
{% endblock %}
{% block haha %}
{% endblock %}
</body>
#children.html(此处没有省略内容,就是全部内容,不是像上面只在body区域)
{% extends "father.html" %}
{% block haha %}
我是从儿子来的haha
{% endblock %}
{% block body %}
我是从儿子来的body
{% endblock %}

#app.py
@app.route('/static')
def static_demo():
return render_template("static.html")
#static.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{{ url_for('static',filename='css/style.css') }}">
<script src="{{ url_for('static',filename='js/my.js') }}"></script>
</head>
<body>
<img src="{{ url_for('static',filename='images/cat.png') }}" alt="">
</body>
</html>
static静态文件设置如下


结果如下


先安装好
pip install pymysql
pip install flask-sqlalchemy
在Navicat Premium中创建数据库


点击测试连接



#app.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import text
app = Flask(__name__)
#MySQL所在的主机名
HOSTNAME="127.0.0.1"
#MySQL坚挺的端口号,默认3306
PORT=3306
#连接MySQL的用户名,用自己设置的
USERNAME="root"
#连接MySQL的密码,用自己设置的
PASSWORD="123456"
#MySQL上创建的数据库名
DATABASE="database_learn"
app.config['SQLALCHEMY_DATABASE_URI'] = f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8mb4"
#在app.config中设置好链接数据库的信息,
#然后使用SQLAlchemy(app)创建一个db对象
#SQLAlchemy会自动读取app.config中链接数据库的信息
db=SQLAlchemy(app)
#测试用的代码
with app.app_context():
with db.engine.connect() as conn:
rs=conn.execute(text("select 1"))
print(rs.fetchone())#(1,)表示成功
@app.route('/')
def hello_world(): # put application's code here
return 'Hello World!'
if __name__ == '__main__':
app.run()
这段代码用于配置一个 Flask 应用程序以连接到一个 MySQL 数据库。让我解释一下代码的各个部分:
app.config['SQLALCHEMY_DATABASE_URI']:
这一行代码是在 Flask 应用的配置中设置一个参数,该参数的名称是'SQLALCHEMY_DATABASE_URI'。这个参数用于指定数据库的连接字符串,告诉应用程序如何连接到数据库。f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8mb4":
这是一个格式化字符串 (f-string),它包含了数据库连接的详细信息。让我们逐个解释它:
mysql+pymysql://:这部分指定了数据库的类型。在这里,它表示使用 MySQL 数据库,并且使用 PyMySQL 驱动来连接。{USERNAME}:这是数据库用户名的占位符。通常,你需要将它替换为实际的数据库用户名。{PASSWORD}:这是数据库密码的占位符。你需要将它替换为实际的数据库密码。{HOSTNAME}:这是数据库服务器的主机名或 IP 地址的占位符。你需要将它替换为实际的数据库服务器地址。{PORT}:这是数据库服务器的端口号的占位符。你需要将它替换为实际的数据库服务器端口号。{DATABASE}:这是数据库的名称的占位符。你需要将它替换为实际的数据库名称。?charset=utf8mb4:这部分用于设置数据库的字符集。在这里,它将字符集设置为 UTF-8MB4,这通常用于支持多语言和特殊字符。所以,通过这行代码,你告诉 Flask 应用程序使用指定的用户名、密码、主机名、端口号和数据库名来连接到一个 MySQL 数据库,并且使用 UTF-8MB4 字符集。这个连接字符串将被 SQLAlchemy 使用,以便在应用程序中与数据库进行交互。
这段代码执行了一个非常简单的数据库查询。让我解释一下这段代码的执行流程:
with app.app_context():
这行代码创建了一个 Flask 应用程序上下文。应用上下文是必要的,当你需要在应用程序的请求/响应周期之外访问应用程序的各个部分时,通常用于执行一些与应用程序相关的操作。with db.engine.connect() as conn:
这一部分建立了一个数据库连接。它似乎使用了 SQLAlchemy 中的数据库引擎 (db.engine) 来创建连接,并将其赋值给conn。这表示你准备与数据库进行交互。rs = conn.execute(text("select 1")):
这行代码执行了一个 SQL 查询。它使用了text()函数创建了一个文本类型的 SQL 查询,这个查询非常简单,只是选择了整数1。然后,execute()方法将这个查询发送给数据库连接 (conn) 来执行,并将执行结果存储在rs中。print(rs.fetchone()):
这部分代码从查询结果中获取了第一行,并将其打印到控制台上。根据你的注释,查询的结果应该是(1,),这表示查询成功,它返回了一个包含值1的元组。所以,这段代码的主要目的是建立一个应用程序上下文、数据库连接,执行一个非常简单的查询以测试数据库连接,并打印查询结果。结果
(1,)表示查询成功,并且数据库连接已经建立并能够执行查询。这种代码常常用于测试数据库连接或验证数据库是否可用。
class User(db.Model):
__tablename__ = 'user'
id=db.Column(db.Integer,primary_key=True,autoincrement=True)
username=db.Column(db.String(100),nullable=False)
password=db.Column(db.String(100),nullable=False)
with app.app_context():
db.create_all()
这段代码涉及到使用 SQLAlchemy 和 Flask 来定义一个数据库模型和创建数据库表格的过程。让我为你解释:
class User(db.Model):
这部分代码定义了一个名为User的数据库模型类。这类通常用于映射到数据库表格。它继承自db.Model,这表明它是一个 SQLAlchemy 模型。__tablename__ = 'user':
这一行指定了数据库表格的名称,即'user'。数据库表格名称通常与模型类名相同,但小写字母,并且通常使用复数形式,但在这里明确指定了表格名称。- 模型类的属性:
id: 这是模型类的一个属性,代表用户的唯一标识。它是一个整数字段 (db.Integer),标记为主键 (primary_key=True),并且会自动递增 (autoincrement=True),这意味着每当插入一条新用户记录时,这个字段的值将自动递增,以确保唯一性。username: 这是用户的用户名字段,它是一个字符串字段 (db.String(100)),并且不能为空 (nullable=False),这意味着用户名是必填的。password: 这是用户的密码字段,它也是一个字符串字段 (db.String(100)),并且不能为空 (nullable=False),这意味着密码也是必填的。with app.app_context()::
这行代码创建了一个 Flask 应用上下文,允许你在应用程序上下文中执行操作。这是必要的,因为你需要在应用程序上下文中创建数据库表格。db.create_all():
这行代码使用 SQLAlchemy 中的create_all()方法来创建数据库表格,具体创建的表格是根据定义的模型类来确定的。在这里,它会创建一个名为 ‘user’ 的数据库表格,该表格与User模型类相关联。总之,这段代码定义了一个
User数据库模型类,其中包含了用户的唯一标识、用户名和密码字段。然后,它在应用上下文中使用db.create_all()来创建与模型相关的数据库表格。这使得你可以在应用程序中存储和检索用户数据。


点击设计表可以看更详细的信息


@app.route("/user/add")
def add_user():
#1.创建ORM对象
user=User(username='jack',password='123456')
#2.将ORM对象添加到db.session中
db.session.add(user)
#3.将db.session中的改变同步到数据库中
db.session.commit()
#4.在页面返回结果
return "用户创建成功!"
@app.route("/user/query")
def query_user():
#1.get查找:根据主键查找
user=User.query.get(1)
print(f"{user.id}:{user.username}:{user.password}")
#2.filter_by查找
#Query:类数组
users=User.query.filter_by(username='jack')
for user in users:
print(user.username)
return "数据查找成功"
@app.route("/user/update")
def update_user():
user=User.query.filter_by(username='jack').first()
user.password='123'
db.session.commit()
return "数据修改成功!"
@app.route("/user/delete")
def delete_user():
user=User.query.get(1)
db.session.delete(user)
db.session.commit()
return "数据删除成功!"
让我详细解释每个路由处理函数的代码和功能:
/user/add- 添加用户
@app.route("/user/add")
def add_user():
# 1. 创建ORM对象
user = User(username='jack', password='123456')
# 2. 将ORM对象添加到db.session中
db.session.add(user)
# 3. 将db.session中的改变同步到数据库中
db.session.commit()
# 4. 在页面返回结果
return "用户创建成功!"
user,用户名为 “jack”,密码为 “123456”。db.session) 中,这相当于将用户信息标记为要插入到数据库中。db.session.commit() 来提交会话中的更改,将用户信息插入到数据库中。
/user/query- 查询用户
@app.route("/user/query")
def query_user():
# 1. get查找: 根据主键查找
user = User.query.get(1)
print(f"{user.id}:{user.username}:{user.password}")
# 2. filter_by查找
users = User.query.filter_by(username='jack')
for user in users:
print(user.username)
return "数据查找成功"
get() 方法,根据主键(ID)查找 ID 为 1 的用户。filter_by() 方法根据用户名 “jack” 查找所有匹配的用户记录,并将它们存储在 users 中。users 对象来打印匹配的用户的用户名。
/user/update- 更新用户
@app.route("/user/update")
def update_user():
user = User.query.filter_by(username='jack').first()
user.password = '123'
db.session.commit()
return "数据修改成功!"
filter_by() 方法找到用户名为 “jack” 的用户记录,并获取到第一个匹配的用户。db.session.commit() 来提交更改,即将用户信息更新到数据库中。
/user/delete- 删除用户
@app.route("/user/delete")
def delete_user():
user = User.query.get(1)
db.session.delete(user)
db.session.commit()
return "数据删除成功!"
get() 方法找到 ID 为 1 的用户记录。db.session.delete(user) 将用户对象从数据库会话中标记为删除。db.session.commit() 来提交更改,即从数据库中删除用户。这些路由处理函数演示了如何使用 Flask 和 SQLAlchemy 进行基本的数据库操作,包括添加、查询、更新和删除用户记录。通过 ORM,你可以以面向对象的方式管理数据库操作,使其更加直观和易于理解。这个应用程序针对用户管理提供了基本的增删改查功能。

(每次操作完后,数据库都要刷新一下才能更新,点下面红框里的比较方便)

先在user表里添加一个数据/user/add

class Article(db.Model):
__tablename__='article'
id=db.Column(db.Integer,primary_key=True,autoincrement=True)
title=db.Column(db.String(200),nullable=False)
content=db.Column(db.Text,nullable=False)
#添加作者的外键
author_id=db.Column(db.Integer,db.ForeignKey('user.id'))
author=db.relationship("User",backref="articles")
@app.route("/article/add")
def article_add():
article1=Article(title='第一篇文章',content='第一篇文章的内容')
article1.author=User.query.get(2)
article2=Article(title='第二篇文章',content='第二篇文章的内容')
article2.author=User.query.get(2)
db.session.add_all([article1,article2])
db.session.commit()
return "文章添加成功!"
@app.route("/article/query")
def query_article():
user=User.query.get(2)
for article in user.articles:
print(article.title)
return "文章查找成功!"
这两行代码是在SQLAlchemy的模型定义中用来建立数据库表之间关系的重要部分。让我解释一下这两行代码的作用:
author_id=db.Column(db.Integer, db.ForeignKey('user.id')):
- 这一行代码定义了一个名为
author_id的列,它是整数类型(db.Integer)。- 通过
db.ForeignKey('user.id'),它创建了一个外键约束,将author_id列关联到另一个表中的数据。具体来说,它将author_id列与名为’user’的表中的’id’列关联起来,以建立作者(User)和文章(Article)之间的关系。- 这意味着
author_id将包含对用户表中特定用户的引用,以指示谁是文章的作者。
author=db.relationship("User", backref="articles"):
- 这一行代码定义了一个名为
author的属性,使用db.relationship来建立模型之间的关系。author属性创建了一个连接到’User’模型的关系。这表示每个’article’对象都将有一个author属性,用于指定该文章的作者。backref="articles"参数在’User’模型中创建一个反向关系,允许您从用户对象访问与该用户相关的所有文章。这就是为什么您可以在query_article路由中使用user.articles来获取用户的所有文章的原因。总之,这两行代码一起建立了"Article"和"User"模型之间的关系,使您能够轻松地将文章与其作者关联,并在需要时获取特定用户的所有文章。
如果在数据库中没有
author属性,那是因为author是在Python代码中的SQLAlchemy模型中定义的,而不是实际的数据库列。在SQLAlchemy中,author是一个关系属性,而author_id是数据库中的外键列。关系属性通常用于在模型中建立表之间的关系,而不会直接映射到数据库表中的列。
当你查询文章对象时,你可以通过article.author来访问文章的作者,这是因为SQLAlchemy会在运行时执行查询以获取相关的作者。这是ORM(对象关系映射)的优点之一,它允许你在Python中轻松地访问和操作数据库表之间的关系,而不需要手动编写SQL查询。
虽然数据库中没有author列,但在Python代码中的SQLAlchemy模型中定义的关系属性使你能够方便地访问和管理文章与其作者之间的关系。当你查询文章时,SQLAlchemy会自动执行必要的查询来获取相关的作者信息。
如果我们print(article2.author)会得到


之前db.create_all()是有弊端的,如果一个表里新添了某个列,是没办法加上去的
所以我们后面几乎不用这种,改用通过flask-migrate
#添加库
from flask_migrate import Migrate
migrate=Migrate(app,db)
然后在终端执行这3步
#ORM模型映射成表的3步
#1. flask db init:这步只需执行一次
#2. flask db migrate :识别ORM模型的改变,生成迁移脚本
#3. flask db upgrade:运行迁移脚本,同步到数据库中