第2章 路由

学习目标

  • 掌握注册路由的方式,能够独立完成路由的注册

  • 掌握URL传递参数的方式,能够通过URL规则向视图函数传递参数

  • 掌握转换器用法,能够根据业务需求灵活应用内置转换器或自定义转换器

  • 掌握指定请求方式,能够在注册路由时指定请求方式

  • 掌握请求钩子,能够在程序中灵活运用请求钩子

  • 掌握上下文,能够通过上下文处理程序中的请求

  • 了解响应报文,能够说出响应报文的组成部分及其作用

  • 掌握响应的创建方式,能够灵活通过make_response()函数生成响应

  • 掌握URL反向解析,能够通过url_for()获取反向解析的URL

  • 掌握页面重定向,能够通过redirect()对页面进行重定向

通过第1章的学习,我们已经对Flask框架有了初步的认识,但是这对使用Flask框架进行项目开发来说还远远不够,因此需要进一步学习Flask框架的知识。本章将针对注册路由、URL传递参数、处理请求等相关内容进行介绍。

2.1 注册路由

在Flask程序中,浏览器通过URL发送HTTP请求给Web服务器,Web服务器再将HTTP请求转发给Flask程序。Flask程序接收到HTTP请求后,需要知道Flask程序中哪部分代码对这个请求进行处理。为此,Flask程序保存了一个URL与视图函数或类的映射关系,建立映射关系的过程称为注册路由。

路由注册完成后,当浏览器根据URL访问网站时会执行Flask程序中与该URL关联的视图函数或类。在Flask中,注册路由一般分为两种方式,一种方式是通过route()方法进行注册,另一种方式是通过add_url_rule()方法进行注册。

1.通过route()方法注册路由

route()是Flask类提供的方法,该方法用于将视图函数与特定的URL建立关联,当通过浏览器访问URL时程序内部自动调用与之关联的视图函数。

route(rule, methods, **options)

rule:必选参数,表示URL规则字符串,该字符串必须以“/”开始。 methods:可选参数,表示HTTP请求方法。 **options:可选参数,表示传递给底层werkzeug.routing.Rule对象的额外选项。

若URL规则字符串以“/”结尾,但用户访问URL时并没有在URL末尾附加“/”,则会自动重定向到附加了“/”的页面;若URL规则字符串的末尾没有附加“/”,但用户通过URL访问页面时在URL末尾附加了“/”,则会出现404页面。

route()方法的用法比较特殊,需要以装饰器的形式写在视图函数的上方。 下面通过一个示例演示如何通过route()方法注册路由,使视图函数与URL建立关联。

from flask import Flask
app = Flask(__name__)
@app.route('/index')    # 通过route()方法注册路由,URL规则为/index
def index():
    return f'<h1>这是首页!</h1>'
if __name__ == '__main__':
    app.run()

2.通过add_url_rule ()方法注册路由

add_url_rule()也是Flask类提供的方法,该方法一般需要传递URL和URL关联的函数名。

add_url_rule(rule, endpoint=None, view_func=None,provide_automatic_options=None, **options)

rule:必选参数,表示URL规则字符串。 endpoint:可选参数,表示端点名称。 view_func:可选参数,表示与端点关联的视图函数名。 methods:可选参数,表示定义的HTTP请求方法。 **options:可选参数,表示传递给底层werkzeug.routing.Rule对象的额外选项。

下面通过示例代码,演示add_url_rule()方法注册路由,使视图函数与URL建立关联。

from flask import Flask
app = Flask(__name__)
def index_new():
    return f'<h1>这是首页!</h1>'
# 通过add_url_rule()方法注册路由
app.add_url_rule(rule='/index', view_func=index_new)
if __name__ == '__main__':
    app.run()

分析route()方法的源码可知,route()方法内部其实调用了add_url_rule()方法,我们可以把route()当作add_url_rule()方法的快捷方法,route()方法的用法更简洁,无需传入与URL规则关联的视图函数名。

在Flask程序中,一个视图函数也可以绑定多个URL,当浏览器访问这些URL时会触发Flask程序中的同一个视图函数,也就是说在浏览器中展示的效果相同。

@app.route('/homepage')
@app.route('/index')
def index():
    return f'<h1>这是首页!</h1>'

2.2 URL传递参数

2.2.1 URL传递参数的方式

当调用route()或add_url_rule()方法注册路由时,可以在URL规则字符串中加入尖括号包裹的变量,用于标记URL中动态变化部分的内容,之后将该变量作为参数传递给视图函数。

<variable_name>

variable_name表示变量名。

通过一个示例演示如何通过URL传递参数,以及在视图函数中如何使用传递的参数。

from flask import Flask
app = Flask(__name__)
@app.route('/<page>')      # URL规则字符串中加入变量page
def page_num(page):        # 将page参数传递给视图函数
    return f'当前为第{page}页'
if __name__ == '__main__':
    app.run()

2.2.2 为参数指定转换器

当URL向视图函数传递参数时,如果需要限定参数的类型,那么可以通过转换器指定参数的类型。

<converter:variable_name>

converter表示转换器,它支持两种类型的转换器,分别是内置转换器和自定义转换器。

1.内置转换器

Flask框架中提供了6种内置转换器。

转换器说明
string默认值,匹配非空字符串,但不包含“/”
any匹配给定的一系列值中的某一个元素
int匹配整型
float匹配浮点型
path与string类似,匹配非空字符串,但允许字符串中包含“/”
uuid匹配UUID字符串

如果为参数明确指定了转换器,那么URL中传递的参数必须符合转换器要求的数据类型。

为URL中传递的参数page显式指定转换器为int。

from flask import Flask
app = Flask(__name__)
@app.route('/<int:page>')
def page_num(page):
    return f'当前为第{page}页'
if __name__ == '__main__':
    app.run()

2.自定义转换器

自定义转换器本质上是一个类,该类需要继承werkzeug.routing模块中的BaseConverter类。BaseConverter类中包含以下一些属性和方法。

regex属性:用于设置正则匹配规则。 to_python()方法:用于将URL中的参数转换为需要传递到视图函数中的类型。 to_url()方法:用于将Python数据类型转换为URL中使用的字符串。

自定义转换器定义完成之后,需要通过url_map.converters添加到转换器字典中。添加自定义转换器的格式如下所示。

程序实例.url_map.converters["自定义转换器名称"]=自定义转换器的类名 

以匹配手机号码的转换器为例演示如何定义和使用自定义转换器。

from flask import Flask
from werkzeug.routing import BaseConverter
app = Flask(__name__)
class MobileConverter(BaseConverter):  # 自定义转换器
    regex = "1[3-9]\d{9}$"  # 定义匹配手机号码的规则
app.url_map.converters["mobile"] = MobileConverter # 添加到转换器字典
@app.route("/user/<mobile:mobile>")
def index(mobile):
    return f'手机号为:{mobile}'
if __name__ == '__main__':
    app.run()

多学一招:UUID

UUID是通用唯一识别码(Universally Unique Identifier)的缩写,它是一种软件建构的标准,用于让分布式系统中的所有元素都能有唯一的辨识信息。如此一来,每个人都可以创建不与其他人冲突的UUID。 UUID由32位数的16进制数字所构成,以连字符“-”分隔成五组来显示,形式为 8-4-4-4-12例如,223e1234-a99b-12d3-a426-5266cd448472。

2.3 处理请求

2.3.1 指定请求方式

当我们在浏览器的地址栏中输入URL地址后,可以访问网站页面、向网站提交数据、下载网站中的资源,那么网站服务器如何判断要执行哪种操作呢?其实网站服务器会根据HTTP请求方法来处理不同的需求。 在HTTP规范中定义了一组常用的请求方法,例如,GET方法负责从服务器请求某些资源,POST方法会向服务器发送处理的数据等。

HTTP规范中定义的请求方法。

请求方法说明
GET用于请求服务器索要某个资源
POST用于向服务器提交表单或上传文件,表单数据或文件的数据会包含在请求体中
HEAD类似GET方法,但服务器返回的响应中没有具体内容,只有响应头部
PUT从客户端向服务器传送的数据取代指定的文档的内容
DELETE用于请求服务器删除指定的资源
OPTIONS允许客户端查看服务器支持的各项功能
PATCHPUT方法的补充,用于对已知资源进行局部更新

Flask程序中同样支持发送HTTP规范中的请求方法,我们可以在使用装饰器route()或add_url_rule()方法注册路由时传入参数methods来指定使用的请求方法,该参数会以列表形式接收一种或多种请求方法。

在Flask程序的视图函数中,默认的请求方式为GET,而HEAD和OPTIONS这两个请求方法由Flask自动处理。

在Flask2.0及其之后的版本提供了指定部分请求方式的便捷函数,这些函数与请求方法的名称相同,且都是小写形式的。

get():route()传递methods=["GET"]的快捷函数。 post():route()传递methods=["POST"]的快捷函数。 put():route()传递methods=["PUT"]的快捷函数。 delete():route()传递methods=["DELETE"]的快捷函数。 patch():route()传递methods=["PATCH"]的快捷函数。

在Flask程序中使用上述快捷函数,只需要通过装饰器的形式添加到在视图函数上方即可。

@app.post('/login')
def login():
    pass

2.3.2 请求钩子

在开发Flask程序时,一个网站中可能有多个功能需要判断用户的身份,为了避免让每个视图函数编写判断用户身份的功能代码,Flask提供了注册通用函数的功能,即请求钩子。

Flask提供的请求钩子及其说明。

请求钩子说明
before_first_request注册一个函数,用于在处理第一个请求之前执行,后续请求将不再执行
before_request注册一个函数,用于在每一次请求之前执行
after_request注册一个函数,该函数需要接收响应对象作为参数。若程序没有抛出异常,则会在每次请求后执行该函数
teardown_request注册一个函数,即使程序有未处理的异常,也在每次请求之后执行该函数。如果程序发生异常,需要将该异常信息作为参数传入注册的函数中
after_this_request在视图函数内注册一个函数,用于在这个请求后执行,该函数需要接收响应对象作为参数

请求钩子注册的函数名称是开发者自定义的,无需与请求钩子名称相同。请求钩子都会在请求处理的不同阶段执行,请求钩子的调用流程。

from flask import Flask, after_this_request

app = Flask(__name__)
@app.before_first_request
def before_first_request():
    print('这是请求钩子before_first_request注册的函数')
@app.before_request
def before_request():
    print('这是请求钩子before_request注册的函数')
@app.route('/index')
def index():
    print('hello flask')
    @after_this_request
    def after_this_request_func(response):
        print('这是请求钩子after_this_request注册的函数')
        return response
    return 'hello flask'
@app.after_request
def after_request(response):
    print('这是请求钩子after_request注册的函数')
    return response
@app.teardown_request
def teardown_request(error):
    print('这是请求钩子teardown_request注册的函数')


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

2.3.3 上下文

Flask使用上下文临时保存了程序运行过程中的一些信息。Flask中有两种上下文,分别是请求上下文和应用上下文,其中应用上下文是随着请求上下文产生而产生,随着请求上下文销毁而销毁。

1.请求上下文

Flask的请求上下文包括request对象和session对象,其中request对象封装了请求信息;session对象用于记录请求会话中的用户信息。 request对象中提供了用于处理请求信息的常用属性。

request对象中提供了用于处理请求信息的常用属性。

属性说明
args获取URL中的请求参数
methods获取请求的HTTP方法
cookies获取包含Cookie名称和值的字典对象
data获取包含字符串形式的请求数据
form获取解析后的表单数据
values一个包含form和args全部内容的CombineMultiDict
headers获取首部字段
user_agent获取浏览器标识信息

request对象中提供了用于处理请求信息的常用方法。

方法说明
close()关闭当前请求
get_data()获取请求中的数据
get_json()作为JSON解析并返回数据
make_form_data_parse()创建表单数据解析器
from flask import Flask, request

app = Flask(__name__)
@app.route('/index')
def index():
    user_agent = request.user_agent  # 获取浏览器标识信息
    return f'{user_agent}'
if __name__ == '__main__':
    app.run()

因为HTTP是无状态的协议,也就是说浏览器发起的每个HTTP请求,对于服务器而言都是彼此独立的,所以服务器无法判断请求是否由同一个浏览器发送。为了能够判断接收的请求是否由同一浏览器发送的,服务器通常会通过会话跟踪技术实现状态保持,常用的会话跟踪技术有Cookie和Session,其中Cookie通过在浏览器记录信息确定用户身份;Session通过在服务端记录信息确定用户身份,它通常依赖于Cookie。

在Flask的请求上下文中,session对象用于管理Session,以实现状态保持。session对象实现状态保持的原理如下。

当服务器收到浏览器发送的请求时,会检查浏览器中是否包含名称为session的Cookie信息,如果不存在,那么浏览器会认为当前请求是一个新会话,并生成一个名称为session的信息存储到浏览器的Cookie中。 浏览器在下一次请求服务器时,将携带Cookie中存储的session信息,此时服务器通过浏览器提交的session信息便可以辨别出当前请求属于哪个浏览器。

在Flask中,session对象提供了很多获取Cookie信息的方法。

方法说明
get(key)通过传入的key值,获取Cookie中对应的value值
pop(key)通过传入的key值,删除Cookie中对应的value值
items()将Cookie中的值以“key:value”形式返回
values()获取Cookie中所有的value值
clear()清空当前站点Cookie中的内容
keys()获取Cookie中所有的key值
update()接收一个字典,根据接收的字典更新或添加到Cookie中
from flask import Flask, request, session
app = Flask(__name__)
app.secret_key = 'Your_seccret_key&^52@!'   		# 设置secret_key的值
@app.route('/index')
def index():
    if 'username' in session:
        return f'你好:{session.get("username")}'
    return '请登录'
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username'] # 设置session值
        return '登录成功'
    return '''
        <form method="post">
            <p><input type=text name=username>
            <p><input type=submit value='登录'>
        </form>
    '''
if __name__ == '__main__':
    app.run()

2.应用上下文

Flask的应用上下文包括current_app对象和g对象,其中current_app对象表示当前激活的Flask应用程序实例;g对象表示程序的一个全局临时变量,我们可以通过g对象在一次请求调用的多个函数间传递一些数据,每次请求都会重设这个变量。

from flask import Flask, current_app  # 导入current_app对象
app = Flask(__name__)
app.secret_key = 'Your_seccret_key&^52@!'
@app.route('/')
def index():
    return f'{current_app.secret_key}'   # 通过current_app对象获取密钥
if __name__ == '__main__':
    app.run()

g对象存储了一次请求的所有用户信息,例如,用户的登录信息、数据库的连接信息等,在同一个请求中,如果后续的代码中需要用户登录信息或数据库连接信息都可以通过g对象获取。当请求完成之后,g对象便会销毁;当发送一个新的请求时,g对象也会随之生成。

使用g对象模拟获取当前用户信息。

from flask import Flask, g
app = Flask(__name__)
@app.route('/')
def get_user():
    user_id = '001'            # 设置用户id
    user_name = 'flask'        # 设置用户名称
    g.user_id = user_id      # 将用户id保存到g对象中
    g.user_name = user_name # 将用户名称保存到g对象中
    result = db_query()
    return f'{result}'
def db_query():
    user_id = g.user_id    # 使用g对象获取用户id
    user_name = g.user_name  # 使用g对象获取用户名称
    return f'{user_id}:{user_name}'
if __name__ == '__main__':
    app.run()

2.4 处理响应

2.4.1 响应报文

在Flask程序中,浏览器发出的请求会触发相应的视图函数,并将视图函数的返回值作为响应体,之后生成完整的响应内容,即响应报文。响应报文主要由4个部分组成,分别是状态行、响应报头、空行以及响应体。

状态行主要由协议版本、状态码和原因短语组成,其中协议版本表示网站服务器使用的传输协议以及版本,例如HTTP/1.0;状态码表示响应内容的状态;原因短语是对状态码的简单说明。 状态码由三位数字组成,其中第1位数字表示响应的类别,它的取值为1~5,其中1xx代表请求已接收,需要继续处理;2xx代表请求已经成功被服务器接收、理解并接受;3xx代表客户端需要进一步细化请求,4代表客户端的请求有错误,5代表服务器出现错误。

状态码取值的说明。

状态码说明
100~199表示服务器成功接收部分请求,要求客户端继续提交其余请求才能完成整个处理过程
200~299表示服务器成功接收请求并已完成整个处理过程,常用的状态码为200,表示请求成功
300~399为完成请求,客户需进一步细化请求。例如,请求的资源已经移动到一个新地址,常用状态码包括302(表示所请求的页面已经临时转移至新的URL)、307和304(表示使用缓存资源)
400~499客户端的请求有错误,常用状态码包括404(表示服务器无法找到被请求的页面)和403(表示服务器拒绝访问,权限不够)
500~599服务器端出现错误,常用状态码为500,表示请求未完成,服务器遇到不可预知的情况

响应报头用于为客户端提供一些额外的信息,通过这些额外的信息可以告知客户端更多的响应信息,包括服务器的名称和版本、响应体的类型等信息。响应报头由多个字段与值组成,字段与值之间以冒号进行分隔。

响应报文中常见的字段说明。

字段说明
Age服务器从创建响应到当前持续的时间,单位为秒
Server服务器应用程序软件的名称和版本
Content-Type服务器发送的响应体的类型
Content-Encoding告知客户端采用哪种解码方式对响应体进行解码
Content-Length响应体的长度

Content-Type字段的常用取值为text/plain、text/html和application/json,分别表示响应内容是纯文本、HTML或JSON。

2.4.2 生成响应

Flask内部自动会该字符串转换成Response类的对象。在Flask中,Response类表示响应,它封装了响应报文的相关信息。如果希望在Flask程序中主动生成响应,一般可以通过Response类的构造方法或make_response()函数实现。

1.Response类的构造方法

Response类的构造方法的声明。

Response(response, status, headers, mimetype, content_type, direct_passthrough)

response:可选参数,表示视图函数返回的响应体。 status:可选参数,表示响应状态码。 headers:可选参数,表示响应报头。 mimetype:可选参数,表示响应体的MIME类型。 content_type:可选参数,表示响应体的类型。

以Response类的构造方法为例,为大家演示如何通过Response类的构造方法生成响应。

from flask import Flask, Response
app = Flask(__name__)
@app.route('/index')
def index():
    # 使用Response类的构造方法生成响应对象,设置状态码为201,响应类型为text/html
    resp = Response(response='基于Python的Flask服务器开发',status=201,
                                 content_type='text/html;charset=utf-8')
    return resp
if __name__ == '__main__':
    app.run()

2.make_response()函数

make_response()函数也用于生成响应,它可以接收str、bytes、dict和tuple共4种类型的参数,当参数的类型为tuple时,参数的值可以为(body, status, headers) 、(body, status)或 (body, headers)任意一种形式,其中body表示响应体,status表示状态码,headers表示响应报头,另外header的值可以是一个字典或(key,value)形式的元组。

演示如何通过make_response()函数生成响应。

from flask import Flask, make_response
app = Flask(__name__)
@app.route('/index')
def index():
    res = make_response('Python&Flask',201,
                            {'content-type':' text/html;charset=utf-8'})
    return res
if __name__ == '__main__':
    app.run()

若视图函数返回的响应体为JSON格式的字符串,我们可以通过json模块将Python字典、列表或元组序列化为JSON格式的字符串,也可以通过Flask提供的便捷函数jsoinify(),jsonify()函数会将传入的参数序列化为JSON格式的字符串。两者的区别在于,前者会将响应类型设置为text/html,而后者会将响应类型设置为application/json。

演示如何通过make_response()函数生成JSON类型的响应数据。

from flask import Flask, make_response, jsonify
app = Flask(__name__)
@app.route('/response')
def resp():
    res = make_response(jsonify({'Python':'Flask'}),202)
    return res
if __name__ == '__main__':
    app.run()

2.5 URL反向解析

使用Flask开发程序时我们可以以硬编码的方式在程序中使用URL,但此种方式会使URL与程序具有较高的耦合度,当某个URL修改之后,程序中与之对应的URL都需要进行同步修改,这样不仅不利于URL的维护,还可能因为忘记修改URL导致程序出现错误。

flask.url_for模块中提供了URL反向解析的函数url_for(),该函数可以根据视图函数的名称获取对应的URL。

url_for(endpoint, values,_external,_scheme,_anchor,_method,**values)

endpoint:必选参数,表示反向解析的端点(用于标记一个视图函数以及对应的URL规则)名称,默认值为视图函数名。 values:可选参数,表示URL地址传递的参数。 _external:可选参数,表示是否供程序外部使用,默认值为False,若为True,则返回绝对URL地址,例如,http://127.0.0.1:5000/hello/flask。

使用url_for()函数对URL进行反向解析。

from flask import Flask, url_for
app = Flask(__name__)
@app.route('/hello/flask')
def greet():
    return f"{url_for('greet')}"   # 反向解析视图函数greet()对应的URL
if __name__ == '__main__':
    app.run()

若URL规则中包含要传递的参数,则调用url_for()函数时需要将该参数以关键字参数形式传递。

from flask import Flask, url_for
app = Flask(__name__)
@app.route('/hello/<name>')
def greet(name):
    return f"{url_for('greet',name=name)}"   
if __name__ == '__main__':
    app.run()

 

使用url_for()函数反向解析URL时,除了传递URL规则中的参数以外,还可以传递任何额外参数给URL地址的参数。

from flask import Flask, url_for
app = Flask(__name__)
@app.route('/hello/<name>')
def greet(name):
    # 将age=20添加到URL地址中
    return f"{url_for('greet',name=name, age=20)}"
if __name__ == '__main__':
    app.run()

多学一招:URL编码

URL编码是一种用于将URL中的非ASCII字符的特殊字符转换为可以为Web浏览器和服务器可以接受的字符。在Flask中,url_for()函数可以对URL地址中的一些特殊字符自动编码,例如,URL地址为/hello/zhangsan?addr=北京,url_for()函数会将其编码为/hello/zhangsan?address=%E5%8C%97%E4%BA%AC。

2.6 页面重定向

页面重定向在Web程序中非常普遍,例如,当用户在电商网站购买商品时,电商网站若检测到用户还未曾登录,则会将当前页面重定向到登录页面。在Flask程序中,页面重定向功能可以通过redirect()函数实现。

redirect(location, code=302, Response=None)

location:必选参数,表示重定向的URL地址。 code:可选参数,表示重定向状态码,默认状态码为302。 Response:可选参数,表示实例化响应时使用的Response类,若未指定默认使用的响应类为werkzeug.wrappers.Response。

通过一个用户登录的案例演示如何通过redirect()函数实现登录页面与欢迎页面的重定向,即当用户首次访问欢迎页面时,若session中还没有记录过这个用户名,则会将欢迎页面重定向到登录页面;当用户在登录页面输入用户名登录后,会将登录页面重定向到欢迎页面。

 

from flask import Flask, url_for, request, redirect, session
app = Flask(__name__)

app.secret_key = 'Your_secret_key&^52@!'
@app.route('/index')
def index():
    if 'username' in session:
        return f'你好:{session.get("username")}'  # 返回欢迎信息
    return redirect(url_for("login"))  # 页面重定向到登录页面
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('index'))  # 页面重定向到欢迎页面
    # 当发送GET请求时,页面显示输入框和登录按钮
    return '''
        <form method="post">
            <p><input type=text name=username>
            <p><input type=submit value=登录>
        </form>
    '''

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

多学一招:唯一的URL

在浏览器中访问某些页面时,我们可以看到有些页面的URL地址末尾包含“/”,有些URL地址末尾没有包含“/”,例如,http://127.0.0.1:5000/static/goods/和http://127.0.0.1:5000/static/goods,这两个地址从表面上看非常相似,但它们访问的结果是不同的,前者访问的是goods目录下的资源,比如book.jpg或tea.jpg文件,而后者访问的是goods资源。由此可见,http://127.0.0.1:5000/static/goods/和http://127.0.0.1:5000/static/goods是两个不同的URL地址。

当我们在Flask程序中注册路由时,若URL地址以“/”结尾,但用户请求相应页面时使用的URL地址末尾没有加“/”,则会将当前页面重定向到URL地址加“/”的同一页面。为了保持访问资源的URL唯一,使加“/”和不加“/”的URL地址能指向不同的资源,我们在注册路由时建议URL末尾不加“/”。

以@app.route(‘/static/goods’)和@app.route(‘/static/goods/’)为例,通过一张表来罗列末尾包含和不包含“/”的URL访问结果。

示例URL**地址**是否可访问
@app.route('/static/goods')http://127.0.0.1:5000/static/goods/不可以
@app.route('/static/goods')http://127.0.0.1:5000/static/goods可以
@app.route('/static/goods/')http://127.0.0.1:5000/static/goods/可以
@app.route('/static/goods/')http://127.0.0.1:5000/static/goods可以

2.7 本章小结

本章首先介绍了如何在Flask程序中注册路由并向URL中传递参数,然后介绍了Flask程序接收请求之后如何进行请求处理,接着介绍了如何在Flask程序中处理响应,最后介绍了URL反向解析和页面重定向。通过学习本章的内容,希望读者能够掌握Flask中路由的使用,为后续的学习奠定扎实的基础。

2.8 习题

一,填空题

1.Flask程序中可通过route()和()方法注册路由。

2.自定义转换器需要继承()。

3.自定义转换器定义完成之后,需要通过()将器添加到转换器字典中。

4.Flask程序中,URL字符串中使用()标识变量。

5.Flask中上下文分为请求上下文和()。

二,判断题

1.在Flask程序中,一个视图函数可以绑定多个URL规则。()

2.Flask的请求上下文包括request对象和g对象。()

3.使用jsonify()函数可以将响应数据序列化为JSON格式的字符串。()

4.Flask使用上下文临时保存程序运行过程中的一些信息。()

5.常用的会话跟踪技术有Cookie和Session。()

三,选择题

1.下列选项中,用于在使用add_url_rule()方法注册路由时设置端点名称的参数是()。

A.rule

B.endpoint

C.view_func

D.methods

2.下列选项中,用于匹配整型数据的内置转换器是()。

A.string

B.any

C.int

D.float

3.下列选项中,用于获取URL中请求参数的是()。

A.args

B.methods

C.cookies

D.data

4.下列选项中,表示请求成功的状态码是()。

A.100

B.200

C.301

D.400

5.下列选项中,用于从服务器请求某些资源的请求方式是()。

A.PUT

B.HEAD

C.POST

D.GET

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MacOS - 时间如何显示读秒?

mac 上的时间比较精确&#xff0c;所以打算把秒也显示出来&#xff0c;网上搜的大部分都是通过设置来设置的&#xff0c;但是一般会找不到设置&#xff0c;反正我就这里推荐使用命令来设置 在设置中进行设置 Tips&#xff1a;如果没有在设置中找到对应设置可以用以下方案 设置时…

cocos creator 3.x 预制体无法显示

双击预制体&#xff0c;进入详情页&#xff0c;没有显示资源 Bomb 是个预制体&#xff0c;但是当我双击进来什么都没有了&#xff0c;无法对预制体进行可视化编辑 目前我只试出来一个解决方法&#xff1a; 把预制体拖进Canvas文件中&#xff0c;这样就能展示到屏幕上&#xff…

cesium mapboxgl+threebox glb 朝向问题

一、3Dbuilder打开glb 二、cesium在pitch和heading都为0的情况下&#xff0c;不设置模型的朝向 三、mapboxglthreebox在pitch和bearing都为0的情况下&#xff0c;不设置模型的朝向 四、对于地图默认视角&#xff0c;cesium设置pitch-90、heading0的时候和mapboxglthreebox设置p…

第十五篇【传奇开心果系列】Python的OpenCV库技术点案例示例:图像配准

传奇开心果短博文系列 系列短博文目录Python的OpenCV库技术点案例示例系列短博文目录前言一、常见的图像配准任务介绍二、图像配准任务:图像拼接介绍和示例代码三、图像配准任务:图像校正介绍和示例代码四、图像配准任务:图像配准介绍和示例代码五、基于特征点的配准方法介绍…

【Langchain+Streamlit】旅游聊天机器人

【LangchainStreamlit】打造一个旅游问答AI-CSDN博客 项目线上地址&#xff0c;无需openai秘钥可直接体验&#xff1a;http://101.33.225.241:8502/ github地址&#xff1a;GitHub - jerry1900/langchain_chatbot: langchainstreamlit打造的一个有memory的旅游聊天机器人&…

ctfshow-命令执行(web73-web77)

web73 用不了上一题的通用poc了 因为禁用了strlen 但是可以改一个函数自定义一个函数只要是能实现strlen效果即可 cvar_export(scandir(/));exit(0); 根目录下有一个flagc.txt文件 cinclude(/flagc.txt);exit(0); web74 禁用了scandir函数 那就使用web72的glob协议 查看目录下…

3D室内虚拟灭火体验为预防火灾提供全新方案

室内火灾常见于充电器未拔、电动车、油锅起火及煤气泄露等原因&#xff0c;由于室内空间小、易燃物多&#xff0c;因此极易造成较大的人员财产损失&#xff0c;3D仿真还原技术、通过1&#xff1a;1模拟还原火灾发生全过程&#xff0c;火灾VR安全培训提供全方位、真实感强的模拟…

休斯顿NASA太空机器人进入最后测试阶段,或可模拟人类执行外星任务!

美国宇航局开发研制的太空智能机器人目前正在德州休斯顿的约翰逊航天中心接受最后的运行测试&#xff0c;距离太空智能化时代又要更进一步了&#xff01; NASA表示&#xff0c;日前在德州休斯顿附近的约翰逊航天中心进行测试的机器人名为Valkyrie&#xff0c;是以北欧神话中的一…

每日一题——LeetCode1422.分割字符串的最大得分

方法一 暴力枚举 枚举所有分割点的情况&#xff0c;取最大得分 var maxScore function(s) {let res 0;const n s.length;for (let i 1; i < n; i) {let score 0;for (let j 0; j < i; j) {if (s[j] 0) {score;}}for (let j i; j < n; j) {if (s[j] 1) {sco…

修改JDK文件路径或名称(以及修改后jJRE文件变红的解决)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

电缆线的阻抗50Ω,真正含义是什么?

当我们提到电缆线的阻抗时&#xff0c;它到底是什么意思&#xff1f;RG58电缆通常指的是50Ω的电缆线。它的真正含义是什么&#xff1f;假如取一段3英尺(0.9144米)长的RG58电缆线&#xff0c;并且在前端测量信号路径与返回路径之间的阻抗。那么测得的阻抗是多少&#xff1f;当然…

opensatck中windows虚拟机CPU核数显示异常问题处理

文章目录 一、问题描述二、元数据信息三、以32核的实例模版为例3.1 单槽位32核3.2 双槽位32核 总结 一、问题描述 openstack创建windows虚拟机的时候&#xff0c;使用普通的实例模版会出现CPU数量和实例模版不一致的问题。需要定制元数据才可以正常显示。 帖子&#xff1a;htt…

基于java+springboot+vue实现的房屋租赁管理系统(文末源码+Lw)23-142

第1章 绪论 房屋租赁管理系统管理系统按照操作主体分为管理员和用户。管理员的功能包括报修管理、字典管理、租房房源管理、租房评价管理、房源租赁管理、租房预约管理、论坛管理、公告管理、投诉建议管理、用户管理、租房合同管理、管理员管理。用户的功能等。该系统采用了My…

Oracle 面试题 | 15.精选Oracle高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

常用的前端模块化标准总结

1、模块化标准出现以前使用的模块化方案&#xff1a; 1&#xff09;文件划分&#xff1a; 将不同的模块定义在不同的文件中&#xff0c;然后使用时通过script标签引入这些文件 缺点&#xff1a; 模块变量相当于是定义在全局的&#xff0c;容易造成变量名冲突&#xff08;即不…

【Qt】Android上运行keeps stopping, Desktop上正常

文章目录 问题 & 背景背景问题 解决方案One More ThingTake Away 问题 & 背景 背景 在文章【Qt】最详细教程&#xff0c;如何从零配置Qt Android安卓环境中&#xff0c;我们在Qt中配置了安卓开发环境&#xff0c;并且能够正常运行。 但笔者在成功配置并完成上述文章…

图书|基于Springboot的图书管理系统设计与实现(源码+数据库+文档)

图书管理系统目录 目录 基于Springboot的图书管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、个人中心 2、管理员管理 3、用户管理 4、图书出版社管理 5、公告类型管理 6、所在书架管理 7、图书类型管理 8、论坛管理 9、公告信息管理 10、图书信…

解决zabbix图像中文乱码

使用zabbix查看监控图像信息&#xff0c;发现会有中文乱码现象。 解决方法如下&#xff1a; 1.拷贝windows文字文件到服务器上 C:\Windows\Fonts目录下拷贝自己需要的中文语言文件 2.修改配置文件 vim /usr/share/zabbix/include/defines.inc.php 81行 define(ZBX_GRAPH_F…

DolphinScheduler本地安装

文章目录 前言1. 安装部署DolphinScheduler1.1 启动服务 2. 登录DolphinScheduler界面3. 安装内网穿透工具4. 配置Dolphin Scheduler公网地址5. 固定DolphinScheduler公网地址 前言 本篇教程和大家分享一下DolphinScheduler的安装部署及如何实现公网远程访问&#xff0c;结合内…

vue教程-介绍与使用

vue介绍 介绍 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是&#xff0c;Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层&#xff0c;不仅易于上手&#xff0c;还便于与第三方库或既有项目整合。 安装 最简单的例子就是&#xff0c;创建一个htm…