Flask简介
Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。Flask使用 BSD 授权。
Flask也被称为 “microframework” ,因为它使用简单的核心,用 extension 增加其他功能。Flask没有默认使用的数据库、窗体验证工具。
安装
pip install flask -i https://mirrors.aliyun.com/pypi/simple
创建项目
项目目录结构
static
存放静态文件
templates
存放jinja2模板文件
app.py
项目启动入口
基本内容如下:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world(): # put application's code here
return 'Hello World!'
if __name__ == '__main__':
app.run()
启动项目并访问
启动
默认端口是5000
访问
修改配置
debug模式
- 开启debug模式后,修改代码保存,就会自动重新加载,不需要手动重启项目
- 开发的时候出现bug,开启debug模式,会在浏览器上看到出错信息
修改host
就是让其他电脑访问自己电脑上的flask项目
修改port端口号
路由和视图的映射
无参路由
类似于这样:
@app.route('/')
@app.route('/login')
有参路由
@app.route('/blog/<blog_id>')
def get_blog(blog_id):
return f'您获取的博客id是:{blog_id}'
可以为参数定义类型
@app.route('/blog/<int:blog_id>')
def get_blog(blog_id):
return f'您获取的博客id是:{blog_id}'
不定参数
需求:
/book/list:返回首页数据
/book/list?page=2:返回第二页数据
@app.route('/book/list')
def book_list():
# 如果无参数 默认是1
page = request.args.get("page", default=1, type=int)
return f"当前是第{page}页"
无参数
有参数
Jinja2模板渲染
Jinja2 是一个强大的 Python 模版引擎,主要用于生成HTML或其他文本文件。这个库非常适合开发动态网站和Web应用的视图层,因为它支持逻辑操作如循环和条件判断,还可以继承和重用模板。Jinja2以其灵活性和性能著称。
在templates文件夹中创建html文件
加载html文件
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def hello_world(): # put application's code here
return render_template("index.html")
if __name__ == '__main__':
app.run()
测试
向html中传参
编写路由代码
@app.route("/blog/<id>")
def get_blog(id):
return render_template("blog_detail.html", blog_id=id)
编写前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>博客详情</title>
</head>
<body>
<h1>获取的博客编号是:{{ blog_id }}</h1>
</body>
</html>
测试
模板访问对象属性
构建类和字典
class User:
def __init__(self, name, age):
self.name = name
self.age = age
@app.route('/')
def hello_world(): # put application's code here
user = User("yohoo", 28)
person = {
"username": "zz",
"password": "123"
}
return render_template("index.html", user=user, person=person)
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h2>yohoo的测试首页</h2>
<h3>姓名:{{ user.name }}</h3>
<h3>年龄:{{ user.age }}</h3>
<hr>
<h3>用户名:{{ person.username }}</h3>
<h3>密码:{{ person.password }}</h3>
</body>
</html>
测试
遍历列表
创建列表
@app.route("/books")
def get_books():
books = ['python', 'go', 'java']
return render_template("books.html", book_list=books)
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图书列表</title>
</head>
<body>
<ul>
{% for b in book_list %}
<li>{{ b }}</li>
{% endfor %}
</ul>
</body>
</html>
测试
过滤器
变量可以通过 过滤器 修改。过滤器与变量用管道符号( | )分割,并且也 可以用圆括号传递可选参数。多个过滤器可以链式调用,前一个过滤器的输出会被作为后一个过滤器的输入。
计算字符串长度
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>过滤器</title>
</head>
<body>
<h2>{{ a }}-字符串长度{{ a|length }}</h2>
</body>
</html>
自定义过滤器
# 自定义过滤器
def date_format(value, format="%Y-%m-%d"):
return value.strftime(format)
app.add_template_filter(date_format, "dformat")
@app.route("/format_time")
def format_time():
t = datetime.now()
return render_template("date.html", t=t)
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>{{ t|dformat }}</h2>
</body>
</html>
条件判断
格式
{% if 条件1 %}
语句块1
{% elif 条件2 %}
语句块2
{% else %}
不符合所有条件
{% endif %}
代码
@app.route("/str_test")
def str_test():
l = ['sss', 'dfdsfdfdf', 'eteet', 'fffffff']
return render_template("demo01.html", l=l)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul>
{% for s in l %}
{% if s|length > 6 %}
<li>{{ s }}</li>
{% elif s|length > 4 %}
<li>大于4</li>
{% else %}
<li>小于等于4</li>
{% endif %}
{% endfor %}
</ul>
</body>
</html>
测试
模板继承
子页面继承父页面
格式
父页面内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<ul>
<li>python</li>
<li>java</li>
</ul>
{% block body %}
{% endblock %}
</body>
</html>
子页面1
{% extends "father.html" %}
{% block title %}
我是子模版1标题
{% endblock %}
{% block body %}
我是子模版1内容
{% endblock %}
子页面2
{% extends "father.html" %}
{% block title %}
我是子模版2标题
{% endblock %}
{% block body %}
我是子模版2内容
{% endblock %}
代码
@app.route("/child1")
def child1():
return render_template("child1.html")
@app.route("/child2")
def child1():
return render_template("child2.html")
测试
加载静态文件
格式
img标签
<img src="{{ url_for('static',filename='文件地址') }}">
link标签
<link rel="stylesheet" href="{{ url_for('static',filename='文件地址') }}">
script标签
<script src="{{ url_for('static',filename='文件地址') }}"></script>
代码
静态文件目录结构
static.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="{{ url_for('static',filename='js/hello.js') }}"></script>
<link rel="stylesheet" href="{{ url_for('static',filename='css/demo.css') }}">
</head>
<body>
<div id="container">
<h2>测试</h2>
</div>
<img src="{{ url_for('static',filename='images/lol.jpg') }}">
</body>
</html>
后端代码
@app.route("/static")
def static_demo():
return render_template("static.html")
测试
js生效
css和图片生效
Flask连接MySQL数据库
选择mysql驱动和orm
pip install pymysql -i https://mirrors.aliyun.com/pypi/simple
pip install flask-sqlalchemy -i https://mirrors.aliyun.com/pypi/simple
整体代码
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import text
app = Flask(__name__)
# 主机名
HOSTNAME = "127.0.0.1"
# 端口
PORT = 3306
# 用户名
USERNAME = "root"
# 密码
PASSWORD = "xxxx"
# 数据库名称
DATABASE = "database_learn"
app.config['SQLALCHEMY_DATABASE_URI'] = f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:" \
f"{PORT}/{DATABASE}?charset=utf8mb4"
# 在app.config中设置好连接数据库的信息,
# 在app.config中设置好连接数据库的信息
# 然后使用SQLAlchemy(app)创建一个db对象
db = SQLAlchemy(app)
# 测试数据库是否连接成功
with app.app_context():
with db.engine.connect() as conn:
rs = conn.execute(text("select 1"))
print(rs.fetchone())
if __name__ == '__main__':
app.run()
成功显示
ORM模型与表映射
ORM 全拼Object-Relation Mapping,中文意为 对象-关系映射。主要实现模型对象到关系数据库数据的映射。ORM提供了一种面向对象操作数据库的方式给开发者。不需要编写原生SQL语句也能操作数据库,实现了业务代码与底层数据的解耦。
优点
只需要面向对象编程, 不需要面向数据库编写SQL.
对数据库的操作都转化成对类/对象的属性和方法的操作. 表字段—>对象属性, SQL关键字-> 操作方法
不用编写各种数据库的原生sql语句,当然,也可以编写原生SQL语句。
实现了数据模型代码与数据库数据的解耦, 屏蔽了不同数据库操作上的差异
不再需要关注当前项目使用的是哪种数据库。
通过简单的配置就可以轻松更换数据库, 而不需要修改业务代码.
创建User类
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()
测试
数据库生成user表
ORM模型的CRUD操作
添加
代码
@app.route("/user/add")
def add_user():
user = User(username="yohoo", password="123")
db.session.add(user)
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查找
users = User.query.filter_by(username="yohoo")
for user in users:
print(user.username)
print(user.password)
print(user.id)
return "数据查询成功"
测试
修改
代码
@app.route("/user/update")
def update_user():
# 主键存在的情况可以使用
user = User.query.get(1)
user.password = "111"
db.session.commit()
return "用户修改成功"
测试
删除
代码
@app.route("/user/delete")
def delete_user():
user = User.query.get(1)
db.session.delete(user)
db.session.commit()
return "删除用户成功"
测试
ORM模型外键与表关系
创建带有外键的类
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"))
# backref自动给user模型自动添加article属性,用来获取文件列表
author = db.relationship("User", backref="articles")
新增文章
代码
@app.route("/article/add")
def article_add():
article1 = Article(title="学习python", content="非常值得读取")
article1.author = User.query.get(2)
article2 = Article(title="学习java", content="从入门到精通")
article2.author = User.query.get(2)
db.session.add_all([article1, article2])
db.session.commit()
return "文章添加成功"
测试
通过用户id查找文章
代码
@app.route("/article/query")
def query_article():
user = User.query.get(2)
for article in user.articles:
print(article.title)
return "文章查找成功"
测试
flask-migrate迁移ORM模型
db.create_all只能处理新增的表模型,如果在已经存在的模型上新增字段就不能更新了
这里使用flask-migrate来处理
安装
pip install flask-migrate -i https://mirrors.aliyun.com/pypi/simple
导入
from flask_migrate import Migrate
使用
migrate = Migrate(app, db)
ORM映射三部曲
第一
flask db init
第二(识别ORM模型的改变,生成迁移脚本)
flask db migrate
第三(运行迁移脚本,同步到数据库中)
flask db upgrade
案例
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)
email = db.Column(db.String(100), nullable=False)
新增email字段
执行三部曲
结果