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 Flaskapp = Flask(__name__)@app.route('/')
def hello_world(): # put application's code herereturn '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():# 如果无参数 默认是1page = 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_templateapp = Flask(__name__)@app.route('/')
def hello_world(): # put application's code herereturn 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 = nameself.age = age@app.route('/')
def hello_world(): # put application's code hereuser = 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 textapp = 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字段
执行三部曲
结果