url_for()反向解析

版权声明:FatPuffer https://blog.csdn.net/qq_42517220/article/details/88713953

URL / 重定向行为

       以下两条规则的不同之处在于是否使用尾部的斜杠。

@app.route('/projects/')
def projects():
    return 'The project page'

@app.route('/about')
def about():
    return 'The about page'

       projects 的 URL 是中规中举的,尾部有一个斜杠,看起来就如同一个文件夹。 访问一个没有斜杠结尾的 URL 时 Flask 会自动进行重定向,帮你在尾部加上一个斜杠。

       about 的 URL 没有尾部斜杠,因此其行为表现与一个文件类似。如果访问这个 URL 时添加了尾部斜杠就会得到一个 404 错误。这样可以保持 URL 唯一,并帮助 搜索引擎避免重复索引同一页面,所以推荐使用

URL 构建

       url_for() 函数用于构建指定函数的 URL。它把函数名称作为第一个参数。它可以接受任意个关键字参数,每个关键字参数对应 URL 中的变量。未知变量 将添加到 URL 中作为查询参数。
       为什么不在把 URL 写死在模板中,而要使用反转函数 url_for() 动态构建?

  • 反转通常比硬编码 URL 的描述性更好。
  • 你可以只在一个地方改变 URL ,而不用到处乱找。
  • URL 创建会为你处理特殊字符的转义和 Unicode 数据,比较直观。
  • 生产的路径总是绝对路径,可以避免相对路径产生副作用。
  • 如果你的应用是放在 URL 根路径之外的地方(如在 /myapplication 中,不在 / 中), url_for() 会为你妥善处理。

例如,这里我们使用 test_request_context() 方法来尝试使用 url_for() 。 test_request_context() 告诉 Flask 正在处理一个请求,而实际上也许我们正处在交互 Python shell 之中, 并没有真正的请求.

from flask import Flask, url_for

app = Flask(__name__)

@app.route('/')
def index():
    return 'index'

@app.route('/login')
def login():
    return 'login'

@app.route('/user/<username>')
def profile(username):
    return '{}\'s profile'.format(username)

with app.test_request_context():
    print(url_for('index'))
    print(url_for('login'))
    print(url_for('login', next='/'))
    print(url_for('profile', username='John Doe'))

/
/login
/login?next=/
/user/John%20Doe

本地环境

       某些对象在 Flask 中是全局对象,但不是通常意义下的全局对象。这些对象实际上是 特定环境下本地对象的代理

       设想现在处于处理线程的环境中。一个请求进来了,服务器决定生成一个新线程,当 Flask 开始其内部请求处理时会把当前线程作为活动环境,并把当前应用和 WSGI 环境绑定到 这个环境(线程)。它以一种聪明的方式使得一个应用可以在不中断的情况下调用另一个应用。

       这个只有在做单元测试时才有用。在测试 时会遇到由于没有请求对象而导致依赖于请求的代码会突然崩溃的情况。对策是自己创建 一个请求对象并绑定到环境。最简单的单元测试解决方案是使用 test_request_context() 环境管理器。通过使用 with 语句 可以绑定一个测试请求,以便于交互。

from flask import request

with app.test_request_context('/hello', method='POST'):
    # now you can do something with the request until the
    # end of the with block, such as basic assertions:
    assert request.path == '/hello'
    assert request.method == 'POST'

# 另一种方式是把整个 WSGI 环境传递给 request_context() 方法:

from flask import request

with app.request_context(environ):
    assert request.method == 'POST'

test_request_context(* args,** kwargs )

参数 说明
path 请求的URL路径
base_url 提供应用程序的基本URL, path相对于。如果没有给出,从建 PREFERRED_URL_SCHEME,subdomain, SERVER_NAME,和APPLICATION_ROOT
subdomain 要追加的子域名 SERVER_NAME
url_scheme 使用的方案代替 PREFERRED_URL_SCHEME
data 请求正文,可以是字符串,也可以是表单键和值的字典
json 如果给定,则将其序列化为JSON并传递为 data。也默认content_type为 application/json
args 传递给的其他位置参数 EnvironBuilder
kwargs 传递给其他关键字参数 EnvironBuilder

       创建一个RequestContext根据给定的值创建一个WSGI环境。这在测试期间非常有用,您可能希望在不调度完整请求的情况下运行使用请求数据的函数。

       使用with块来推送上下文,这将 request指向创建环境的请求。

with test_request_context(...):
    generate_report()
def generate_report(year):
    format = request.args.get('format')
    ...

with app.test_request_context(
        '/make_report/2017', data={'format': 'short'}):
    generate_report()

       在 shell 中创建一个正确的请求情境的最简便的方法是使用 test_request_context 方法。这个方法会创建一个 RequestContext :

>>> ctx = app.test_request_context()

       通常你会使用 with 语句来激活请求对象,但是在 shell 中,可以简便地手动使用 push() 和 pop() 方法:

>>> ctx.push()

       从这里开始,直到调用 pop 之前,你可以使用请求对象:

>>> ctx.pop()

发送请求前/后动作。

       仅仅创建一个请求情境还是不够的,需要在请求前运行的代码还是没有运行。比如, 在请求前可以会需要转接数据库,或者把用户信息储存在 g 对象中。
       使用 preprocess_request() 可以方便地模拟请求前/后动作:

>>> ctx = app.test_request_context()
>>> ctx.push()
>>> app.preprocess_request()

       请记住, preprocess_request() 函数可以会返回一个响应对 象。如果返回的话请忽略它。如果要关闭一个请求,那么你需要在请求后函数(由 process_response() 触发)作用于响应对象前关闭:

>>> app.process_response(app.response_class())
<Response 0 bytes [200 OK]>
>>> ctx.pop()

teardown_request() 函数会在环境弹出后自动执行。我们可以 使用这些函数来销毁请求情境所需要使用的资源(如数据库连接)。

猜你喜欢

转载自blog.csdn.net/qq_42517220/article/details/88713953