flask_基础

01-Flask 第一个项目

image-20250513171156004

static 文件夹: 用来存放静态文件

templates 文件夹:用来存放Jinja2 模版

app.py:项目的入口文件

# 从flask 这个包中导入 Flask 类
from flask import Flask

# 使用 Flask 类创建一个app 对象
# __name__: 代表当前 app.py 模块
app = Flask(__name__)

# 创建一个路由和视图函数的映射
@app.route('/')
def hello_world():  # put application's code here
    return 'Hello World!'


if __name__ == '__main__':
    app.run()

02-debug, host, 和 port 的配置

image-20250513191700340

1.在 pycharm 中 可以通过如上图所示 开启或者关闭 flask app 的 debug 模式, 可以通过如下图方式修改 host 和 port 设置。

image-20250515165317509

image-20250515165922924

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello_world():  # put application's code here
    return 'Hello World! 哦哦哦'

# debug 模式
"""
1.开启debug 模式后, 修改代码,保存后,会自动重启加载修改后的代码,不需要手动重启
2. 如果开发的时候,出现 bug, 如果开启了debug 模式,在浏览器上就可以看到出错信息。
"""
# 修改 host
# 主要作用: 就是让其他电脑能访问到我电脑上的flask 项目

# 修改 端口号
# 默认端口是 5000 端口, 可以通过 pycharm -> Flask(app.py) -> edit configurations 修改 端口
if __name__ == '__main__':
    app.run()
    # 开启 debug 模式的第二种方式
    # app.run(debug=True)


03-URL 和视图的映射

定义 url 可以分为 无参数的 url 和 有参数的url, 无参数的url 直接传递路径就可以了,

1 有参数 的url可以在路由 中指定 url 的类型和 变量名, 然后传递给相关的视图函数,

类似于:

@app.route("/blog/<int:blog_id>")
def blog_detail(blog_id):
    return "我是博客{}".format(blog_id)

2 使用 flask 中的 request

from flask import request

# 查询字符的方式传参
# 访问 相关视图函数时 使用 ?参数=xx 的方式
# 可以使用 request.args.get("参数") 获取参数值

# 查询字符的方式传参
# /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}页的图书列表!"

from flask import Flask, request

app = Flask(__name__)

# url 由 什么组成
"""
# 协议: http/https 
# 域名: http[80]/https[443]://www.qq.com:443/path
# 在用浏览器访问网站时,因为 http 默认用的是 80 端口, https 默认用的是
443 端口,浏览器会自动指定端口号

url 和视图: path 和 视图
"""

# 定义 无参的 url
@app.route('/')
def hello_world():  # put application's code here
    return 'Hello World!'


@app.route('/profile')
def profile():
    return "个人中心"


@app.route("/blog/list")
def blog_list():
    return "我是博客列表"


# 定义有参的 url: 将参数固定到了 path 中
@app.route("/blog/<int:blog_id>")



# 查询字符的方式传参
# /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}页的图书列表!"


if __name__ == '__main__':
    app.run()


04-Jinja2-模版渲染

渲染模版, 利用到了 Jinja2 模块,因为 flask渲染模版依赖于 JInja2 , 所以安装 flask 的时候,也自动安装了 Jinja2 模块

通过利用 flask 中的 render_template,传入 html 文件,来渲染展示 html

from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def hello_word():
    # 项目文件夹下的templates 中有index.html 文件
    return render_template("index.html")


if __name__ == '__main__':
    app.run()

在模版中渲染动态变化的东西

通过利用 render_template 函数 将 参数 传递到 html 模版中 ,在模版文件中 使用 {{ 变量名 }} ,获取相关的变量值

@app.route("/blog/<blog_id>")
def blog_detail(blog_id):
    # 将获取的参数传递到 模版文件中
    return render_template("blog_detail.html", blog_id=blog_id, username="hhh")

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>博客详情</title>
</head>
<body>
<h1>您访问的博客详情是:{{ blog_id }}</h1>
<h2>我的名字是 {{ username }}</h2>
</body>
</html>

05-Jinja2-模版访问对象属性

当传入 到模版html 文件中的是一个对象 或者一个字典的时候

都可以使用 **对象.属性 字典.属性 **来访问对象中的属性, 字典的话还可以使用 字典["属性名"]来获取

class User:
    def __init__(self, username, email):
        self.username = username
        self.email = email


@app.route('/')
def hello_word():
    user = User(username="uuu", email="sss@qq.com")
    person = {
        "username": "iii",
        "email": "yye@qq.com"
    }
    return render_template("index.html", user=user, person=person)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>嘿嘿嘿, 这里是首页</h1>
<div>{{ user.username }} / {{ user.email }}</div>
<div>{{ person["username"] }}/ {{ person.username }}</div>
</body>
</html>

06-Jinja2-过滤器的使用

过滤器: 传入 html 模版中的变量, 需要经过一定的处理以后, 才可以使用, 这里处理变量的 函数称为过滤器

使用 管道符连接| 连接需要处理的 内容

这里的 length 就是一个过滤器, 用来获取 传入内容的字符串 长度
{{ user.username }} - {{ user.username|length }} 
from flask import Flask, render_template

app = Flask(__name__)


class User:
    def __init__(self, username, email):
        self.username = username
        self.email = email
        
@app.route("/filter")
def filter_demo():
    user = User(username="小明222", email="xx@qq.com")
    return render_template("filter.html", user=user)


if __name__ == '__main__':
    app.run()
<! filter.html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>过滤器的使用</title>
</head>
<body>
{{ user.username }} - {{ user.username|length }}
</body>
</html>

访问 filter 视图函数的输出

image-20250515201612288

自定义过滤器

已经存在的过滤器不能够满足要求,可以自己写函数

from datetime import datetime

# 自定义过滤器
# value 是传递给过滤器的值, return 是 过滤器处理后返回的值
def datetime_format(value, format1="%Y-%d-%m %H: %M"):
    return value.strftime(format1)


app.add_template_filter(datetime_format, "dformat")


@app.route("/filter")
def filter_demo():
    user = User(username="小明222", email="xx@qq.com")
    mytime = datetime.now()
    return render_template("filter.html", user=user, mytime=mytime)

<! filter.html>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>过滤器的使用</title>
</head>
<body>
<div>
{{ user.username }} - {{ user.username|length }}

</div>
<div> {{ mytime|dformat }}</div>
</body>
</html>

访问视图函数的输出

image-20250515203248861

07-Jinja2 中的控制语句

if 控制语句

在 html 模版文件中使用{% if %} {% elif %} {% else %} {% endif %} 来实现

@app.route("/control")
def control_statement():
    age = 18
    return render_template("control.html", age=age)
<! control.html>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>控制语句</title>
</head>
<body>
{% if age > 18 %}
    <div>您已经满18岁, 可以进入网吧!</div>
{% elif age==18 %}
    <div>您刚满18岁, 需要父母陪同才能进入!</div>
{% else %}
    <div>您未满18岁,不能进入网吧!</div>
{% endif %}
</body>
</html>

for 控制语句

使用 {%for %} {% endfor%}

@app.route("/control")
def control_statement():
    age = 18
    books = [{
        "name": "三国演义",
        "author": "罗贯中"
    },{
        "name": "水浒传",
        "author": "施耐庵"
    }]
    return render_template("control.html", age=age, books=books)

<!control.html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>控制语句</title>
</head>
<body>
 
{% for book in books %}
    <div>图书名称: {{ book.name }}</div>
    <div>图书作者: {{ book.author }}</div>
{% endfor %}
</body>
</html>

08-Jinja2-模版继承

一个网站中,大部分的网页的模块是重复的, 如顶部的导航条,底部的备案信息等等

这里就需要使用到模版继承了, 把一些重复性的代码写在父模版中,子模版继承父模版,分别再实现自己页面的代码。

创建一个 base.html 作为父模版, 创建 child1.html 和 child2.html 作为 子模版继承父模版

在 子模版中用{% extends 父模版名称 %} 例如 : {% extends "base.html" %}

子模版中的一部分内容是和父模版不同的,需要在 父模版中使用 block 占位, 在 子模版中 填充占位

{% block title % } {% endblock%}

<!base.html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %} {% endblock %}</title>
</head>
<body>
<ul>
    <li><a href="#">首页</a></li>
    <li><a href="#">新闻</a></li>
</ul>

{% block body %}
{% endblock %}

<footer>这是底部的标签</footer>
</body>
</html>
<!child2.html>

{% extends "base.html" %}

{% block title %}
    我是 child2
{% endblock %}

{% block body %}
    我是 child2
{% endblock %}
@app.route("/child2")
def child2():
    return render_template("child2.html")

09-Jinja2中加载静态文件

如何在 html 中加载图片, 加载 css 文件, 加载 js 文件

使用 url_for()函数指定需要加载的文件的 文件位置和文件名

例如 :url_for("static", filename="images/11.img")

在 html 中加载 图片使用 img 标签

加载 css 文件使用 link 标签

加载 js 文件使用 script标签

<!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/学习.jpeg") }}" alt="">
</body>
</html>
body{
    background-color: pink;
}
修改背景颜色
alert("我是my.js 中执行的");

在加载网页时,alert 一个信息

10-Flask连接mysql数据库

python 有一个 pymysql 模块可以 对mysql 数据库进行操作, 在 Flask 中 更多的使用的是 SQLAlchemy 提供的 ORM 技术,来

操作数据库,Flask_SQLAlchemy 是对 SQLAlchemy 的一个封装,

pip install pymysql
pip install flask-sqlalchemy
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import text

app = Flask(__name__)

# mysql 配置信息

# MySQL 所在的主机名
HOSTNAME = "127.0.0.1"
# MySQL 监听的端口号
PORT = 3306
# 连接MySQl 的用户名
USERNAME = "root"
# 连接MySQL 的密码
PASSWORD = "root"
# MySQL 上创建的数据库名称
DATABASE = "flask_learning"

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"))  # (1,)
        print(rs.fetchone())


@app.route('/')
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    app.run()

11-ORM模型与表的映射

ORM(Object Relational Mapping 对象关系映射)

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import text

app = Flask(__name__)

# mysql 配置信息

# MySQL 所在的主机名
HOSTNAME = "127.0.0.1"
# MySQL 监听的端口号
PORT = 3306
# 连接MySQl 的用户名
USERNAME = "root"
# 连接MySQL 的密码
PASSWORD = "root"
# MySQL 上创建的数据库名称
DATABASE = "flask_learning"

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)


@app.route('/')
def hello_world():
    return 'Hello World!'

# orm 对象关系映射, python 中的一个类 映射 成数据库中的一个表
# 这个类的一个实例对象,映射成数据库中的一条数据

class User(db.Model):
    __tablename__ = ("user")
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    # 数据库中映射成varchar, null = 0
    username = db.Column(db.String(100), nullable=False)
    password = db.Column(db.String(100), nullable=False)


# user = User(username='xxx', password="333")
# sql: insert user(username, password) values("xxx", "333")
with app.app_context():
    db.create_all()


if __name__ == '__main__':
    app.run()

12-ORM模型的CRUD操作

CRUD(create, read, update, delete)

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import text

app = Flask(__name__)

# mysql 配置信息

# MySQL 所在的主机名
HOSTNAME = "127.0.0.1"
# MySQL 监听的端口号
PORT = 3306
# 连接MySQl 的用户名
USERNAME = "root"
# 连接MySQL 的密码
PASSWORD = "root"
# MySQL 上创建的数据库名称
DATABASE = "flask_learning"

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)


@app.route('/')
def hello_world():
    return 'Hello World!'

# orm 对象关系映射, python 中的一个类 映射 成数据库中的一个表
# 这个类的一个实例对象,映射成数据库中的一条数据


class User(db.Model):
    __tablename__ = ("user")
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    # 数据库中映射成varchar, null = 0
    username = db.Column(db.String(100), nullable=False)
    password = db.Column(db.String(100), nullable=False)


@app.route("/user/add")
def add_user():
    # 1. 创建 ORM对象
    user = User(username="mpp", password="ooo")
    # 2. 将ORM 对象添加到 db.session 中
    db.session.add(user)
    # 3. 将db.session 中的改变同步到数据库中
    db.session.commit()
    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="mpp")
    print(type(users))
    for user in users:
        print(user.username)
    return "数据查找成功"


@app.route("/user/update")
def update_user():
    user = User.query.filter_by(username="mpp").first()
    user.password = "6666"
    db.session.commit()
    return "数据修改成功"


@app.route("/user/delete")
def delete_user():
    # 1. 查找
    user = User.query.get(1)
    # 2. 从 db.session 中删除
    db.session.delete(user)
    # 3. 将db.session 中的 修改,同步到数据库中
    db.session.commit()
    return "数据删除成功!"


if __name__ == '__main__':
    app.run()

13-ORM模型外键和表的关系

一个User 表 和 一个 articles 表,articles 表中有个字段是 author , 可以使用外键的方式,指向User表

在 articles 类模型中, 添加外键用

author_id = db.Column(db.Integer, db.ForeignKey("user.id"))

可以在 两个表中添加 relationship 和 back_populates 使 两个表可以互相查找

article.author 和 author.articles 可以获取到 数据

也可以在 article 表中 使用 backref 不需要在 User 表中添加 articles 的relationship 了

class User(db.Model):
    __tablename__ = ("user")
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    # 数据库中映射成varchar, null = 0
    username = db.Column(db.String(100), nullable=False)
    password = db.Column(db.String(100), nullable=False)

    articles = db.relationship("Article", back_populates="author")


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)

    # 添加作者的外键
    # 添加外键 和 relationship 后, 可以直接通过 article
    # 对象.属性获取到外键的值
    author_id = db.Column(db.Integer, db.ForeignKey("user.id"))
    # 在 当前表和 对应的外键表中 都添加相关的 relationship 和 反向引用 back_populates
    # 可以通过 user.articles 获取一个用户的所有文章
    author = db.relationship("User", back_populates="articles")

    # 也可以 在当前表中使用 backref, 不需要在 User 表中添加 articles 的relationship 了
    # author = db.relationship("User", backref="articles")
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import text

app = Flask(__name__)

# mysql 配置信息

# MySQL 所在的主机名
HOSTNAME = "127.0.0.1"
# MySQL 监听的端口号
PORT = 3306
# 连接MySQl 的用户名
USERNAME = "root"
# 连接MySQL 的密码
PASSWORD = "root"
# MySQL 上创建的数据库名称
DATABASE = "flask_learning"

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)


@app.route('/')
def hello_world():
    return 'Hello World!'

# orm 对象关系映射, python 中的一个类 映射 成数据库中的一个表
# 这个类的一个实例对象,映射成数据库中的一条数据


class User(db.Model):
    __tablename__ = ("user")
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    # 数据库中映射成varchar, null = 0
    username = db.Column(db.String(100), nullable=False)
    password = db.Column(db.String(100), nullable=False)

    articles = db.relationship("Article", back_populates="author")


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)

    # 添加作者的外键
    # 添加外键 和 relationship 后, 可以直接通过 article
    # 对象.属性获取到外键的值
    author_id = db.Column(db.Integer, db.ForeignKey("user.id"))
    # 在 当前表和 对应的外键表中 都添加相关的 relationship 和 反向引用 back_populates
    # 可以通过 user.articles 获取一个用户的所有文章
    author = db.relationship("User", back_populates="articles")

    # 也可以 在当前表中使用 backref, 不需要在 User 表中添加 articles 的relationship 了
    # author = db.relationship("User", backref="articles")

with app.app_context():
    db.create_all()


@app.route("/user/add")
def add_user():
    # 1. 创建 ORM对象
    user = User(username="mpp", password="ooo")
    # 2. 将ORM 对象添加到 db.session 中
    db.session.add(user)
    # 3. 将db.session 中的改变同步到数据库中
    db.session.commit()
    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="mpp")
    print(type(users))
    for user in users:
        print(user.username)
    return "数据查找成功"


@app.route("/user/update")
def update_user():
    user = User.query.filter_by(username="mpp").first()
    user.password = "6666"
    db.session.commit()
    return "数据修改成功"


@app.route("/user/delete")
def delete_user():
    # 1. 查找
    user = User.query.get(1)
    # 2. 从 db.session 中删除
    db.session.delete(user)
    # 3. 将db.session 中的 修改,同步到数据库中
    db.session.commit()
    return "数据删除成功!"


@app.route("/article/add")
def article_add():
    article = Article(title="flask学习方法论", content="温故而知新")
    article.author = User.query.get(2)

    article1 = Article(title="Django学习方法论", content="模拟冥想法")
    article1.author = User.query.get(2)
    # 添加到 session 中
    db.session.add_all([article, article1])
    # 同步到session 中的数据到数据库
    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 "文章查找成功"


if __name__ == '__main__':
    app.run()

14-flask-migrate迁移ORM模型

from flask import Flask
app = Flask(__name__)
db = SQLAlchemy(app)

# 下面的 语句虽然可以将新增的模型映射到数据库,但是 检测不到模型字段的变化
with app.app_context():
    db.create_all()
    

使用 flask_migrate 可以起到 ORM 模型 迁移的效果

pip install flask-migrate

from flask import Flask
from flask_migrate import Migrate

app = Flask(__name__)

db = SQLAlchemy(app)

migrate = Migrate(app, db)

# ORM 模型映射成表的三步
# 1. flask db init  类似于 git init 这里只需要执行一次
# 执行完这个命令, 会在项目目录下生成一个新的 migrations 目录

# 2. flask db migrate: 设别ORM 模型的改变, 生成迁移脚步

# 3. flask db upgrade: 运行迁移脚步, 同步到数据库中
posted @ 2025-05-18 00:51  Ref-brief  阅读(40)  评论(11)    收藏  举报