flask_基础
01-Flask 第一个项目

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 的配置

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


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 视图函数的输出

自定义过滤器
已经存在的过滤器不能够满足要求,可以自己写函数
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>
访问视图函数的输出

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: 运行迁移脚步, 同步到数据库中

浙公网安备 33010602011771号