学习Flask框架

news2024/11/24 10:50:26

Flask简介

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

安装

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

创建项目

image-20240930101751765

项目目录结构

image-20240930101830580

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

启动项目并访问

启动

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

路由和视图的映射

无参路由

类似于这样:

@app.route('/')

@app.route('/login')

有参路由

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

image-20240930105729346

可以为参数定义类型

@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}页"

无参数

image-20240930110539223

有参数

image-20240930110604737

Jinja2模板渲染

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

在templates文件夹中创建html文件

image-20240930142426929

加载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()

测试

image-20240930142611894

向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>
测试

image-20240930143352218

模板访问对象属性

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

image-20240930144603779

遍历列表

创建列表
@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>
自定义过滤器
# 自定义过滤器
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>

测试

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 %}
代码
@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>

后端代码

@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

整体代码

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

成功显示

image-20241008161540962

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表

image-20241008163356553

ORM模型的CRUD操作

添加

代码

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

测试

image-20241008164058046

查询

代码

@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

修改

代码

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

测试

image-20241008165706661

删除

代码

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

测试

image-20241008170003650

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

测试

image-20241008175751527

通过用户id查找文章

代码

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

测试

image-20241008180302750

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

执行三部曲

image-20241008181637096

结果

image-20241008181655855

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2197115.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ssm淘乐乐员工购物商城

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码请私聊我 需要定制请私聊 目 录 目 录 III 第1章 绪论 1 1.1 课题背景 1 1.2 课题意义 1 1.3 研究内容 2 第2章 开发环境与技术 3 …

函数编程:让开发完全专注于代码

作为一名开发者&#xff0c;我过去常常被各种环境配置和部署问题困扰&#xff0c;特别是当项目依赖复杂时&#xff0c;总要花费大量时间在配置服务器、调试环境上。最近&#xff0c;我在使用 TitanIDE 后有了一些全新的开发体验&#xff0c;尤其是它的 函数编程 功能&#xff0…

七、安全运营—概念

控制特权帐号&#xff1a; 账号类型&#xff1a;

众数信科AI智能体智慧文旅解决方案——智能旅行助手

智慧文旅解决方案 智能旅行助手方案 利用先进的AI算法 提供个性化旅游体验的智能服务 众数信科AI智能体 产品亮点 旅游路线智能规划 旅游景点智能问答 旅行游记智能生成等 构建旅行实用指南 让旅游更加便捷、高效、智能化 关于我们 众数信科成立于2021年&#xff0c;由…

操作系统 | 学习笔记 | 王道 | 4.1 文件系统基础

4.文件管理 4.1 文件系统基础 4.1.1 文件的基本概念 定义 文件是以计算机硬盘为载体的存储在计算机上的信息集合&#xff0c;在用户进行的输入、输出中&#xff0c;以文件位基本单位。 文件管理系统是实现的文件的访问、修改和保存&#xff0c;对文件维护管理的系统。 文件的…

Ngx+Lua+Redis 快速存储POST数据

系统几万台设备有windows有安卓还有linux系统&#xff0c;每个设备三分钟就会向服务器post设备的硬件信息&#xff0c;数据格式json&#xff0c;后台管理界面只需要最新的数据&#xff0c;不需要历史数据&#xff0c;业务逻辑非常简单&#xff0c;PHP代码就几行&#xff0c;已经…

Python selenium库学习使用实操四

系列文章目录 Python selenium库学习使用实操 Python selenium库学习使用实操二 Python selenium库学习使用实操三 文章目录 系列文章目录[TOC](文章目录) 前言一、元素获取二、选项解析总结 前言 在Python selenium库学习使用实操二中提到了下拉框的操作&#xff0c;一种是标…

Redis持久化机制(RDBAOF详解)

目录 一、Redis持久化介绍二、Redis持久化方式1、RDB持久化(1) 介绍(2) RDB持久化触发机制(3) RDB优点和缺点(4) RDB流程 2、AOF(append only file)持久化(1) 介绍(2) AOF优点和缺点(3) AOF文件重写(4) AOF文件重写流程 三、AOF和RDB持久化注意事项 一、Redis持久化介绍 Redis…

YOLOv5复现(论文复现)

YOLOv5复现&#xff08;论文复现&#xff09; 本文所涉及所有资源均在传知代码平台可获取 文章目录 YOLOv5复现&#xff08;论文复现&#xff09;概述模型结构正负样本匹配策略损失计算数据增强使用方式训练测试验证Demo 概述 YOLOv5是由Ultralytics公司于2020年6月开源的目标检…

uniapp顶部提示栏实现

效果&#xff1a; 用途&#xff1a;用于展示较短系统通知 实现逻辑&#xff1a; 1.通过请求获取该显示的通知内容&#xff0c;目前所考虑的字段有&#xff1a; {id: 200, // 通知标识&#xff0c;后续会用其阻止用户关闭后无休止开启message: "请勿以系统规定的其它…

与ZoomEye功能类似的搜索引擎还有哪些?(渗透课作业)

与ZoomEye功能类似的搜索引擎有&#xff1a; Shodan&#xff1a;被誉为“物联网的搜索引擎”&#xff0c;专注于扫描和索引连接到互联网的各种设备&#xff0c;如智能家居设备、工业控制系统、摄像头、数据库等。它提供全球互联网设备的可视化视图&#xff0c;帮助用户了解网络…

ssm图书管理系统的设计与实现

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码请私聊我 需要定制请私聊 目 录 摘 要 I Abstract II 第1章 绪论 1 1.1 课题研究背景 1 1.2课题研究现状 1 1.3课题实现目的和意义 …

【C++】模拟实现hash_table(哈希表)

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:实战项目集 ⚙️操作环境:Visual Studio 2022 目录 一.了解项目功能 二.逐步实现项目功能模块及其逻辑详解 &#x1f4cc;实现HashNode类模板 &#x1f38f;构造HashNode类成员变量 &#x1f38f;实现HashNode类构造函数…

高效研究:Zotero的7个插件让你事半功倍

还在为海量文献管理头疼吗?还在为找不到合适的插件犯愁吗?别急,今天我就要带你解锁Zotero的终极武器 - 那些让你爱不释手的必备插件! 作为一个从小白到文献管理达人的过来人,我可以负责任地说:没有这些插件,你的Zotero只能发挥一半功力!安装了这些插件,你的效率绝对能飙升! …

字典树(单词查找树、Trie树)

题目 代码 #include <bits/stdc.h> using namespace std; const int N 1e510; int f[N][26], idx, cnt[N]; void insert(char str[]) {int p 0;for(int i 0; str[i]; i){int u str[i] - a;if(!f[p][u]) f[p][u] idx;p f[p][u];}cnt[p]; } int query(char str[]) …

相亲交友系统的商业模式探讨

在撰写关于相亲交友系统的商业模式探讨时&#xff0c;附带示例代码可能不太合适&#xff0c;因为软文通常是面向非技术读者&#xff0c;讲述商业模式、用户体验等方面的内容。不过&#xff0c;为了满足您的需求&#xff0c;我可以尝试结合一些简单的伪代码&#xff08;模拟代码…

CSS 3D转换

在 CSS 中&#xff0c;除了可以对页面中的元素进行 2D 转换外&#xff0c;您也可以对象元素进行 3D转换&#xff08;将页面看作是一个三维空间来对页面中的元素进行移动、旋转、缩放和倾斜等操作&#xff09;。与 2D 转换相同&#xff0c;3D 转换同样不会影响周围的元素&#x…

Cursor编辑器:10秒生成完美Git提交信息!

Cursor编辑器&#xff1a;10秒生成完美Git提交信息&#xff01; 亲爱的开发者们&#xff0c;是否还在为编写规范的Git提交信息而头疼&#xff1f;今天&#xff0c;就让我们一起揭开Cursor编辑器的神秘面纱&#xff0c;探索如何一键生成专业的Git Commit Message&#xff0c;让…

Android 电源管理各个版本的变动和限制

由于Android设备的电池容量有限&#xff0c;而用户在使用过程中会进行各种高耗电操作&#xff0c;如网络连接、屏幕亮度调节、后台程序运行等&#xff0c;因此需要通过各种省电措施来优化电池使用‌&#xff0c;延长电池续航时间&#xff0c;提高用户体验&#xff0c;并减少因电…

数据结构-八大排序之堆排序

堆排序 1.1 基础知识 原理&#xff1a; 1. 利用完全二叉树构建大顶堆 2. 堆顶元素和堆底元素进行交换&#xff0c;除堆底元素之外其余元素继续构建大顶堆 3. 重复2&#xff0c;直到所有元素都不参与构建 整个数组排序完成 完全二叉树&#xff1a; 数据从上到下&#x…