Flask教程1:flask框架基础入门,路由、模板、装饰器

news2024/11/18 13:59:29

文章目录

        • 一、 简介
        • 二、 概要

一、 简介

Flask是一个非常小的Python Web框架,被称为微型框架;只提供了一个稳健的核心,其他功能全部是通过扩展实现的;意思就是我们可以根据项目的需要量身定制,也意味着我们需要学习各种扩展库的使用。

二、 概要

1)安装: pip install flask
2)组成:WSGI系统、调试、路由
3)模板引擎:Jinja2
4)使用到装饰器:以@开头的代码方法

  1. Flask基础入门
    1)路由route的创建:
    route装饰器详解

通过创建路由并关联函数,实现一个基本的网页:

from flask import Flask

# 用当前脚本名称实例化Flask对象,方便flask从该脚本文件中获取需要的内容
app = Flask(__name__)

#程序实例需要知道每个url请求所对应的运行代码是谁。
#所以程序中必须要创建一个url请求地址到python运行函数的一个映射。
#处理url和视图函数之间的关系的程序就是"路由",在Flask中,路由是通过@app.route装饰器(以@开头)来表示的
@app.route("/")
#url映射的函数,要传参则在上述route(路由)中添加参数申明
def index():
    return "Hello World!"

# 直属的第一个作为视图函数被绑定,第二个就是普通函数
# 路由与视图函数需要一一对应
# def not():
#     return "Not Hello World!"

# 启动一个本地开发服务器,激活该网页
app.run()

点击Running on对应的链接即可跳转到url,路由为默认的@app.route("/"),所以无需调整。返回结果为"Hello World!"

 * Serving Flask app '__main__' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [28/Apr/2024 20:46:02] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [28/Apr/2024 20:46:03] "GET /favicon.ico HTTP/1.1" 404 -

在这里插入图片描述

  • 通过路由的methods指定url允许的请求格式:
from flask import Flask

app = Flask(__name__)

#methods参数用于指定允许的请求格式
#常规输入url的访问就是get方法
@app.route("/hello",methods=['GET','POST'])
def hello():
    return "Hello World!"
#注意路由路径不要重名,映射的视图函数也不要重名
@app.route("/hi",methods=['POST'])
def hi():
    return "Hi World!"

app.run()

默认路由是无法访问的,因为这次两次函数指定路由分别为"/hello""/hi"

在这里插入图片描述
指定对应的路由之后就可以成功访问
在这里插入图片描述
但是对于只接受POST请求的函数,直接访问会报错:Method Not Allowed

在这里插入图片描述

  • 通过路由在url内添加参数,其关联的函数可以接收该参数:

以下为框架自带的转换器,可以置于参数前将接收的参数转化为对应类型

string接受任何不包含斜杠的文本
int接受正整数
float接受正浮点数
path接受包含斜杠的文本

在这里插入图片描述

  • 自定义转换器(pip install werkzeug
from werkzeug.routing import BaseConverter #导入转换器的基类,用于继承方法
from flask import Flask

app = Flask(__name__)

# 自定义转换器类
class RegexConverter(BaseConverter):
    def __init__(self,url_map,regex):
        # 重写父类定义方法
        super(RegexConverter,self).__init__(url_map)
        self.regex = regex

    def to_python(self, value):
        # 重写父类方法,后续功能已经实现好了
        print('to_python方法被调用')
        return value

# 将自定义的转换器类添加到flask应用中
# 具体过程是添加到Flask类下url_map属性(一个Map类的实例)包含的转换器字典属性中
app.url_map.converters['re'] = RegexConverter
# 此处re后括号内的匹配语句,被自动传给我们定义的转换器中的regex属性
# value值会与该语句匹配,匹配成功则传达给url映射的视图函数
@app.route("/index/<re('1\d{10}'):value>")
def index(value):
    print(value)
    return "Hello World!"

if __name__=='__main__':
    app.run(debug=True)
to_python方法被调用
12345678901

在这里插入图片描述

2)endpoint的作用
说明:每个app中都存在一个url_map,这个url_map中包含了urlendpoint的映射;
作用:当request请求传来一个url的时候,会在url_map中先通过rule找到endpoint,然后再在view_functions中根据endpoint再找到对应的视图函数view_func

from flask import Flask

app = Flask(__name__)

# endpoint默认为视图函数的名称
@app.route('/test')
def test():
    return 'test success!'
# 我们也可以在路由中修改endpoint(当视图函数名称很长时适用)
# 相当于为视图函数起别名
@app.route('/hello',endpoint='our_set')
def hello_world():
    return 'Hello World!'

if __name__ == '__main__':
    print(app.view_functions)
    print(app.url_map)
    app.run()
{'static': <function Flask.__init__.<locals>.<lambda> at 0x000001F7AFE2BC70>, 'test': <function test at 0x000001F7AFE70D30>, 
'our_set': <function hello_world at 0x000001F7AFE70DC0>}
Map([<Rule '/static/<filename>' (GET, HEAD, OPTIONS) -> static>,
 <Rule '/test' (GET, HEAD, OPTIONS) -> test>,
 <Rule '/hello' (GET, HEAD, OPTIONS) -> our_set>])
 * Serving Flask app 'test'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:5000

3)request对象的使用
render_template():可以用于呈现一个我们编写的html文件模板
request.method用于获取url接收到的请求方式,以此返回不同的响应页面

#request:包含前端发送过来的所有请求数据

from flask import Flask,render_template,request

# 用当前脚本名称实例化Flask对象,方便flask从该脚本文件中获取需要的内容
app = Flask(__name__)

@app.route("/",methods=['GET','POST'])
#url映射的函数,要传参则在上述route(路由)中添加参数申明
def index():
    if request.method == 'GET':
        # 想要html文件被该函数访问到,首先要创建一个templates文件,将html文件放入其中
        # 该文件夹需要被标记为模板文件夹,且模板语言设置为jinja2
        return render_template('index.html')
    # 此处欲发送post请求,需要在对应html文件的form表单中设置method为post
    elif request.method == 'POST':
        name = request.form.get('name')
        password = request.form.get('password')
        return name+" "+password

if __name__=='__main__':
    app.run()

4)请求钩子before/after_request
想要在正常执行的代码的前、中、后时期,强行执行一段我们想要执行的功能代码,便要用到钩子函数——用特定装饰器装饰的函数。

下面将介绍Flask内,四种常用的钩子:

before_request:在每一次请求之前调用;
该钩子函数表示每一次请求之前,可以执行某个特定功能的函数;
执行顺序是先绑定的先执行;
并且先执行 flask appbefore_request, 再执行 blueprintbefore_request
一般用于检验用户权限、请求是否合法等场景;

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'

@app.before_request
def before_request_a():
    print('I am in before_request_a')
 
@app.before_request
def before_request_b():
    print('I am in before_request_b')
 
 
if __name__ == '__main__':
    app.run()
 * Serving Flask app '__main__' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [29/Apr/2024 11:07:53] "GET / HTTP/1.1" 200 -
I am in before_request_a
I am in before_request_b
  1. before_first_request:与before_request的区别是,只在第一次请求之前调用;
    该钩子函数表示第一次请求之前可以执行的函数;
    执行顺序同样也是先绑定的先执行;
# 代码替换视图函数hello_world后,if main前
@app.before_first_request
def teardown_request_a():
    print('I am in teardown_request_a')

@app.before_first_request
def teardown_request_b():
    print('I am in teardown_request_b')
  1. after_request:每一次请求之后都会调用;
    该钩子函数表示每一次请求之后,可以执行某个特定功能的函数,这个函数接收response对象,所以执行完后必须归还response对象;
    执行的顺序是先绑定的后执行;
    被触发的前提是没有异常抛出,或者异常被 errorhandler捕获并处理;
    一般可以用于产生csrf_token验证码等场景;
# 代码替换视图函数hello_world后,if main前
@app.after_request
def after_request_a(response):
    print('I am in after_request_a')
    # 该装饰器接收response参数,运行完必须归还response,不然程序报错
    return response
 
@app.after_request
def after_request_b(response):
    print('I am in after_request_b')
    return response
  1. teardown_request:每一次请求之后都会调用;
    该钩子函数接收一个参数,该参数是服务器出现的错误信息;
    执行顺序也是先绑定的后执行;
    只有在请求上下文被 pop 出请求栈的时候才会直接跳转到teardown_request
    所以在被正常调用之前,即使某次请求有抛出错误,该请求也都会被继续执行, 并在执行完后返回 response
# 代码替换视图函数hello_world后,if main前
@app.teardown_request
def teardown_request_a(exc):
    print('I am in teardown_request_a')
 
@app.teardown_request
def teardown_request_b(exc):
    print('I am in teardown_request_b')

5)redirect重定向
flask 中,重定向是通过flask.redirect(location, code=302)这个函数来实现的,location表示需要重定向的url, 应该配合url_for函数来使用, code表示采用哪个重定向,默认是302,即临时性重定向, 可以修改为301来实现永性重定向;

from flask import Flask,redirect,url_for

app = Flask(__name__)

@app.route('/index')
def index():
    # redirect重定位(服务器向外部发起一个请求跳转)到一个url界面;
    # url_for给指定的函数构造 URL;
    # return redirect('/hello') 不建议这样做,将界面限死了
    return redirect(url_for('hello'))

@app.route('/hello')
def hello():
    return 'this is hello fun'

if __name__ == '__main__':
    app.run()

在这里插入图片描述
6)返回json数据给前端
方法一:
使用:make_response方法和json库共同完成

from flask import Flask,make_response,json

app = Flask(__name__)

@app.route("/index")
def index():
   data = {
       'name':'张三'
   }
   # json.dumps 将一个python数据结构转化为json
   # json.dumps 序列化时对中文默认使用的ascii编码.想输出真正的中文需要指定ensure_ascii=False
   # 生成一个response响应对象,而不是直接return来返回响应对象,便于执行更多的后续操作
   response = make_response(json.dumps(data,ensure_ascii=False))
   # 修改数据的MIME标准类型为json(在发送数据前会先发送该类型)
   response.mimetype = 'application/json'
   return response

if __name__=='__main__':
    app.run()

在这里插入图片描述
方法二:
使用:jsonify库实现,减少代码行数

from flask import Flask,jsonify

app = Flask(__name__)
# 在Flask的config是一个存储了各项配置的字典
# 该操作是进行等效于ensure_ascii=False的配置
app.config['JSON_AS_ASCII'] = False

@app.route("/index")
def index():
   data = {
       'name':'张三'
   }
   return jsonify(data)

if __name__=='__main__':
    app.run()

7)abort函数的使用
使用类似于python中的raise函数,可以在需要退出请求的地方抛出错误,并结束该请求;
我们可以使用errorhandler()装饰器来进行异常的捕获与自定义:

from flask import Flask,render_template,request,abort

app = Flask(__name__)

@app.route("/",methods=['GET','POST'])
def index():
    if request.method == 'GET':
        return render_template('index.html')
    elif request.method == 'POST':
        name = request.form.get('name')
        password = request.form.get('password')
        if name == 'zhangsan' and password == '123456':
            return 'login sucess'
        else:
            # abort的用法类似于python中的raise,在网页中主动抛出错误
            abort(404)
            return None

# 自定义错误处理方法,将404这个error与Python函数绑定
# 当需要抛出404error时,将会访问下面的代码
@app.errorhandler(404)
def handle_404_error(err):
    # return "发生了错误,错误情况是:%s"%err
    # 自定义一个界面
    return render_template('404.html')

if __name__ == '__main__':
    app.run()
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!-- 注意图片文件需要放在一个静态文件夹static里 -->
<img src="../static/error404.jpg" alt="" width="1428px" height="57px">
</body>
</html>

8)url_for实现反转
url_for是实现url反转的工具,即视图函数 → \rightarrow →url;

静态文件引入:url_for(‘static’, filename=‘文件路径’)

静态文件需要存储在当前工程下的static目录内。

定义路由:url_for(‘模块名.视图名’,变量=参数)

参数一中的视图名实质指的是endpointurl_map中存储了urlendpoint的映射,只是默认情况下endpoint与视图函数名相同;
如果在装饰器中修改了endpoint,则url_for只能使用endpoint设置的名字来反转url
在单模块程序下我们可以省略模块名,但当使用了蓝图(buleprint)后,参数一就必须使用"蓝图模块名.视图名",因为不同蓝图下的视图函数可以重名。

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

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

相关文章

算法:双指针题目练习

目录 题目一&#xff1a;移动零 题目二&#xff1a;复写零 题目三&#xff1a;快乐数 题目四&#xff1a;盛最多水的容器 题目五&#xff1a;有效三角形的个数 题目六&#xff1a;和为s的两个数字(剑指offer) 题目七&#xff1a;三数之和 题目八&#xff1a;四数之和 常…

翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深度学习一

合集 ChatGPT 通过图形化的方式来理解 Transformer 架构 翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深度学习一翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深度学习二翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深…

CAD的DWG文件如何进行搜索文字

1.目的 想搜索CAD文件中的数字或文字是否存在DWG文件中。 2.方法 方式1:菜单栏 编辑→查找 方式2&#xff1a;指令格式 图纸的左下侧→命令处&#xff0c;进行输入find→再按回车enter 3.结果

Day 22 SSH远程管理服务

sshd服务&#xff0c;系统自带&#xff0c;默认开机自启运行 云/物理服务器的安全组和防火墙默认放行该端口 软件包&#xff1a;openssh-server&#xff08;服务端&#xff09;&#xff1b;openssh-client&#xff08;客户端&#xff09;&#xff1b; 格式&#xff1a;ssh I…

【C++语法练习】计算梯形的面积

题目链接&#xff1a;https://www.starrycoding.com/problem/158 题目描述 已知一个梯形的上底 a a a&#xff0c;下底 b b b和高 h h h&#xff0c;请求出它的面积&#xff08;结果保留两位小数&#xff09;。 输入格式 第一行一个整数 T T T表示测试用例个数。 ( 1 ≤ T …

JeeSite主子表

classroom表代码生成配置&#xff08;主表&#xff09; student表代码生成配置&#xff08;子表&#xff09; 设置“班级”菜单 班级列表页面 点击“三年级二班”&#xff0c;显示班级中的学生列表页面 班级表 CREATE TABLE classroom (classroom_id int NOT NULL AUTO_…

Meditron:基于 Llama 完全开源的医学大语言模型

健康危机就在眼前&#xff0c;当医疗资源有限时&#xff0c;每一秒钟都至关重要&#xff01;Meditron 就像一位忠实的医疗助手&#xff0c;提供基于证据的护理建议和情境意识的推荐&#xff0c;帮助医疗工作者在诊断和治疗过程中做出更准确的决策。 在资源有限的医疗环境中&am…

C/C++实现高性能并行计算——1.pthreads并行编程(中)

系列文章目录 pthreads并行编程(上)pthreads并行编程(中)pthreads并行编程(下)使用OpenMP进行共享内存编程 文章目录 系列文章目录前言一、临界区1.1 pi值估计的例子1.2 找到问题竞争条件临界区 二、忙等待三、互斥量3.1 定义和初始化互斥锁3.2 销毁。3.3 获得临界区的访问权&…

《读懂财务报表》手绘版读书笔记:通过报表找好公司

通过财报的三张表判断好公司&#xff1a; 然后是在三表中&#xff0c;计算各个项目占总体的比例&#xff0c;以及做比率分析&#xff0c; 比率分析&#xff0c;从偿还能力&#xff0c;运营能力&#xff0c;盈利能力三方面分析&#xff1a; 1&#xff09; 偿还能力 2&#xff09…

新建stm32工程模板步骤

1.先使用keil新建一个project的基本代码 2.stm32启动文件添加 将stm32的启动文件&#xff0c;在原工程当中新建一个Start文件夹把相关的启动文件放到文件夹当中 然后还需要找到下面三个文件 stm32f10x.h是stm32的外设寄存器的声明和定义&#xff0c;后面那两个文件用于配置系…

Python数据预处理1:导入与基本操作

2024/4/30 After installing the xlrd package, you should be able to read Excel files using pandas without any issues. #需要在pyCharm命令行中下载两个包 pip install pandas pip install xlrd .xls数据导入 #数据的导入 import pandas as pd #导入EXCEL表格数据 df…

Java基于微信小程序+uniapp的校园失物招领小程序(V3.0)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

【大数据】利用 Apache Ranger 管理 Amazon EMR 中的数据权限

利用 Apache Ranger 管理 Amazon EMR 中的数据权限 1.需求背景简介2.系统方案架构图3.主要服务和组件简介3.1 Amazon EMR3.2 Simple Active Directory3.3 Apache Ranger 4.部署步骤4.1 部署 Simple AD 服务4.2 部署 Apache Ranger4.3 部署 Amazon EMR4.4 在 Amazon EMR 的主节点…

FPGA高端项目:FPGA帧差算法多目标图像识别+目标跟踪,提供11套工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐FPGA帧差算法单个目标图像识别目标跟踪 3、详细设计方案设计原理框图运动目标检测原理OV5640摄像头配置与采集OV7725摄像头配置与采集RGB视频流转AXI4-StreamVDMA图像缓存多目标帧差算法图像识别目标跟踪模块视频输出Xilinx系列FPGA工程源…

spring-boot示例

spring-boot版本&#xff1a;2.0.3.RELEASE 数据库: H2数据库 &#xff08;嵌入式内存性数据库&#xff0c;安装简单&#xff0c;方便用于开发、测试&#xff0c;不适合用于生产&#xff09; mybatis-plus框架&#xff0c;非常迅速开发CRUD

Liunx磁盘管理(上)

Liunx磁盘管理&#xff08;中&#xff09;-CSDN博客 目录 一.硬盘类型 机械硬盘&#xff08;HDD&#xff09; 固态硬盘&#xff08;SSD&#xff09; 二.插拔方式 1. 热插拔&#xff08;Hot Swapping&#xff09; 2. 冷插拔&#xff08;Cold Swapping&#xff09; 3. 模块…

新唐的nuc980/nuc972的开发3-官方源码编译

上一节中bsp已经安装&#xff0c;交叉环境已经搭建&#xff0c;理应就可以正常的编写上层的应用程序啦。 但是系统启动次序是- uboot-> kernel内核 ->挂载文件系统 ->上层应用程序 下面是bsp安装后的文件&#xff1a; 因此本章节&#xff0c;将讲解 uboot-> kerne…

MySql-日期分组

一、分别统计各时间各类型数据条数 数据库的 request_time字段 数据类型&#xff1a;timestamp 默认值&#xff1a;CURRENT_TIMESTAMP 例子&#xff1a; 2024-01-26 08:25:48 原数据&#xff1a; 1、将数据按照日期&#xff08;年月日&#xff09;形式输出 按照request_…

C语言:文件操作(下)

片头 嗨&#xff01;小伙伴们&#xff0c;在前2篇中&#xff0c;我们分别讲述了C语言&#xff1a;文件操作&#xff08;上&#xff09;和 C语言&#xff1a;文件操作&#xff08;中&#xff09;&#xff0c;今天我们将会学习文件操作&#xff08;下&#xff09;&#xff0c;准…

电商技术揭秘四十一:电商平台的营销系统浅析

相关系列文章 电商技术揭秘相关系列文章合集&#xff08;1&#xff09; 电商技术揭秘相关系列文章合集&#xff08;2&#xff09; 电商技术揭秘相关系列文章合集&#xff08;3&#xff09; 文章目录 引言一、用户画像与精准营销用户画像与精准营销的概念用户画像在精准营销中…