学习Flask框架

news/2024/12/21 20:09:29/

Flask简介

Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。Flask使用 BSD 授权。
Flask也被称为 “microframework” ,因为它使用简单的核心,用 extension 增加其他功能。Flask没有默认使用的数据库、窗体验证工具。

安装

python">pip install flask -i https://mirrors.aliyun.com/pypi/simple

创建项目

image-20240930101751765

项目目录结构

image-20240930101830580

static

存放静态文件

templates

存放jinja2模板文件

app.py

项目启动入口

基本内容如下:

python">from flask import Flaskapp = Flask(__name__)@app.route('/')
def hello_world():  # put application's code herereturn 'Hello World!'if __name__ == '__main__':app.run()

启动项目并访问

启动

image-20240930102230607

默认端口是5000

image-20240930102251985

访问

image-20240930102323016

修改配置

debug模式

  1. 开启debug模式后,修改代码保存,就会自动重新加载,不需要手动重启项目
  2. 开发的时候出现bug,开启debug模式,会在浏览器上看到出错信息

image-20240930102905555

image-20240930102949728

修改host

就是让其他电脑访问自己电脑上的flask项目

image-20240930104120774

image-20240930104150171

修改port端口号

image-20240930104621554

image-20240930104650120

路由和视图的映射

无参路由

类似于这样:

python">@app.route('/')@app.route('/login')

有参路由

python">@app.route('/blog/<blog_id>')
def get_blog(blog_id):return f'您获取的博客id是:{blog_id}'

image-20240930105729346

可以为参数定义类型

python">@app.route('/blog/<int:blog_id>')
def get_blog(blog_id):return f'您获取的博客id是:{blog_id}'
不定参数

需求:

/book/list:返回首页数据

/book/list?page=2:返回第二页数据

python">@app.route('/book/list')
def book_list():# 如果无参数 默认是1page = request.args.get("page", default=1, type=int)return f"当前是第{page}页"

无参数

image-20240930110539223

有参数

image-20240930110604737

Jinja2模板渲染

Jinja2 是一个强大的 Python 模版引擎,主要用于生成HTML或其他文本文件。这个库非常适合开发动态网站和Web应用的视图层,因为它支持逻辑操作如循环和条件判断,还可以继承和重用模板。Jinja2以其灵活性和性能著称。

在templates文件夹中创建html文件

image-20240930142426929

加载html文件

python">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()

测试

image-20240930142611894

向html中传参

编写路由代码
python">@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>
测试

image-20240930143352218

模板访问对象属性

构建类和字典
python">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>
测试

image-20240930144603779

遍历列表

创建列表
python">@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>
测试

image-20240930151543091

过滤器

变量可以通过 过滤器 修改。过滤器与变量用管道符号( | )分割,并且也 可以用圆括号传递可选参数。多个过滤器可以链式调用,前一个过滤器的输出会被作为后一个过滤器的输入。

计算字符串长度
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>过滤器</title>
</head>
<body>
<h2>{{ a }}-字符串长度{{ a|length }}</h2>
</body>
</html>
自定义过滤器
python"># 自定义过滤器
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 %}
代码
python">@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>

测试

image-20240930162434520

模板继承

子页面继承父页面

格式

父页面内容

<!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 %}
代码
python">@app.route("/child1")
def child1():return render_template("child1.html")@app.route("/child2")
def child1():return render_template("child2.html")
测试

image-20241008151937869

image-20241008152007503

加载静态文件

格式

img标签

<img src="{{ url_for('static',filename='文件地址') }}">

link标签

<link rel="stylesheet" href="{{ url_for('static',filename='文件地址') }}">

script标签

<script src="{{ url_for('static',filename='文件地址') }}"></script>
代码

静态文件目录结构

image-20241008154707268

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>

后端代码

python">@app.route("/static")
def static_demo():return render_template("static.html")
测试

js生效

image-20241008154925460

css和图片生效

image-20241008155205396

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

整体代码

python">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()

成功显示

image-20241008161540962

ORM模型与表映射

ORM 全拼Object-Relation Mapping,中文意为 对象-关系映射。主要实现模型对象到关系数据库数据的映射。ORM提供了一种面向对象操作数据库的方式给开发者。不需要编写原生SQL语句也能操作数据库,实现了业务代码与底层数据的解耦。

优点

只需要面向对象编程, 不需要面向数据库编写SQL.
对数据库的操作都转化成对类/对象的属性和方法的操作. 表字段—>对象属性, SQL关键字-> 操作方法
不用编写各种数据库的原生sql语句,当然,也可以编写原生SQL语句。
实现了数据模型代码与数据库数据的解耦, 屏蔽了不同数据库操作上的差异
不再需要关注当前项目使用的是哪种数据库。
通过简单的配置就可以轻松更换数据库, 而不需要修改业务代码.

创建User类
python">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)
创建表
python">with app.app_context():db.create_all()
测试

数据库生成user表

image-20241008163356553

ORM模型的CRUD操作

添加

代码

python">@app.route("/user/add")
def add_user():user = User(username="yohoo", password="123")db.session.add(user)db.session.commit()return "用户添加成功"

测试

image-20241008164058046

查询

代码

python">@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 "数据查询成功"

测试

image-20241008164905154

修改

代码

python">@app.route("/user/update")
def update_user():# 主键存在的情况可以使用user = User.query.get(1)user.password = "111"db.session.commit()return "用户修改成功"

测试

image-20241008165706661

删除

代码

python">@app.route("/user/delete")
def delete_user():user = User.query.get(1)db.session.delete(user)db.session.commit()return "删除用户成功"

测试

image-20241008170003650

ORM模型外键与表关系

创建带有外键的类
python">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")
新增文章

代码

python">@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 "文章添加成功"

测试

image-20241008175751527

通过用户id查找文章

代码

python">@app.route("/article/query")
def query_article():user = User.query.get(2)for article in user.articles:print(article.title)return "文章查找成功"

测试

image-20241008180302750

flaskmigrateORM_914">flask-migrate迁移ORM模型

db.create_all只能处理新增的表模型,如果在已经存在的模型上新增字段就不能更新了

这里使用flask-migrate来处理

安装
pip install flask-migrate -i https://mirrors.aliyun.com/pypi/simple
导入
python">from flask_migrate import Migrate
使用
python">migrate = Migrate(app, db)

ORM映射三部曲

第一

python">flask db init

第二(识别ORM模型的改变,生成迁移脚本)

python">flask db migrate

第三(运行迁移脚本,同步到数据库中)

python">flask db upgrade

案例

python">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字段

执行三部曲

image-20241008181637096

结果

image-20241008181655855


http://www.ppmy.cn/news/1536583.html

相关文章

JS设计模式之策略模式:灵活、可扩展的编程利器

一. 前言 在 JavaScript 前端开发中&#xff0c;随着代码规模的增长和项目的复杂性&#xff0c;我们常常需要处理各种不同的条件和情况&#xff0c;而这可能导致代码变得冗长、难以维护。这时&#xff0c;我们就需要一种强大而灵活的编程模式来应对这些复杂的逻辑&#xff0c;…

【玩转动态规划专题】70. 爬楼梯【简单】

【玩转动态规划专题】70. 爬楼梯【简单】 1、力扣链接 https://leetcode.cn/problems/climbing-stairs/description/ 2、题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&…

哈夫曼编码

文章目录 &#x1f34a;自我介绍&#x1f34a;哈夫曼编解码&#x1f34a;哈夫曼树介绍&#x1f34a;哈夫曼编码思想 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以&#xff1a;点赞关注评论收藏&#xff08;一键四连&#xff09;哦~ &#x1f34a;自我介绍 Hello,大家…

广州wms智能仓储管理系统 盈致WMS系统服务商

wms智能仓储管理系统是一种用于管理仓库操作和库存流动的软件系统&#xff0c;旨在提高仓库管理效率、降低成本、减少错误和优化库存控制。以下是WMS智能仓储管理系统的主要功能和特点&#xff1a; 入库管理&#xff1a;WMS系统可以实现对入库货物的接收、分拣、上架和入库操作…

JavaScript数字精度丢失问题解决方案

JavaScript数字精度丢失问题 JavaScript使用64位浮点数表示数字&#xff08;基于IEEE 754标准&#xff09;&#xff0c;这导致某些十进制数字在计算过程中出现精度丢失。常见的场景包括小数运算&#xff0c;如 0.1 0.2 的结果并非精确的 0.3&#xff0c;而是 0.3000000000000…

springboot-网站开发-linux服务器部署jar格式图片存档路径问题

springboot-网站开发-linux服务器部署jar格式图片存档路径问题&#xff01;近期在部署自己的网站源码&#xff0c;使用的是jar格式的编码格式。发布到远程服务器后&#xff0c;发现客户捐款的证书图片存在异常。 经过排查代码&#xff0c;找到了原因。下面分享给大家。 1&…

轻量服务器和云服务器ecs哪个好用一些?

轻量服务器和云服务器ecs哪个好用一些&#xff1f;轻量服务器与云服务器ECS在多方面存在显著差异&#xff0c;对于需要高性能计算和大规模数据处理的用户来说&#xff0c;ECS可能是更好的选择&#xff1b;而对于预算有限且需求较为简单的用户来说&#xff0c;轻量服务器可能更为…

N1从安卓盒子刷成armbian

Release Armbian_noble_save_2024.10 ophub/amlogic-s9xxx-armbian (github.com) armbian下载&#xff0c;这里要选择905d adb 下载地址 https://dl.google.com/android/repository/platform-tools-latest-windows.zip 提示信息 恩山无线论坛 使用usb image tool restet a…