Flask中的“端点”是什么?


124

瓶文档显示

add_url_rule(*args, **kwargs)
      Connects a URL rule. Works exactly like the route() decorator.
      If a view_func is provided it will be registered with the endpoint.

     endpoint  the endpoint for the registered URL rule. Flask itself assumes the name of the view function as endpoint

“端点”到底是什么意思?

Answers:


267

烧瓶路由如何工作

Flask(和基础的Werkzeug库)的整个想法是将URL路径映射到您将要运行的某些逻辑(通常是“视图功能”)。基本视图的定义如下:

@app.route('/greeting/<name>')
def give_greeting(name):
    return 'Hello, {0}!'.format(name)

请注意,您引用的函数(add_url_rule)达到了相同的目标,而无需使用装饰符表示法。因此,以下是相同的:

# No "route" decorator here. We will add routing using a different method below.
def give_greeting(name):
    return 'Hello, {0}!'.format(name)

app.add_url_rule('/greeting/<name>', 'give_greeting', give_greeting)

假设您的网站位于“ www.example.org”并使用上述视图。用户在浏览器中输入以下URL:

http://www.example.org/greeting/Mark

Flask的工作是获取此URL,弄清楚用户想要做什么,然后将其传递给许多python函数之一进行处理。它采取的路径

/greeting/Mark

...并将其与路线列表匹配。在我们的案例中,我们定义了该路径以转到give_greeting函数。

但是,尽管这是创建视图的典型方式,但实际上它会从您那里抽象一些额外的信息。在幕后,Flask没有直接从URL跳转到应处理此请求的视图函数。它不只是说...

URL (http://www.example.org/greeting/Mark) should be handled by View Function (the function "give_greeting")

实际上,还有另一步,它将URL映射到端点:

URL (http://www.example.org/greeting/Mark) should be handled by Endpoint "give_greeting".
Requests to Endpoint "give_greeting" should be handled by View Function "give_greeting"

基本上,“端点”是用于确定代码的逻辑单元应处理请求的标识符。通常,端点只是视图函数的名称。但是,您实际上可以更改端点,如以下示例所示。

@app.route('/greeting/<name>', endpoint='say_hello')
def give_greeting(name):
    return 'Hello, {0}!'.format(name)

现在,当Flask路由请求时,逻辑如下所示:

URL (http://www.example.org/greeting/Mark) should be handled by Endpoint "say_hello".
Endpoint "say_hello" should be handled by View Function "give_greeting"

您如何使用端点

该端点通常用于“反向查找”。例如,在Flask应用程序的一个视图中,您想引用另一个视图(例如,当您从站点的一个区域链接到另一个区域时)。您可以使用而不是对URL进行硬编码url_for()。假设以下

@app.route('/')
def index():
    print url_for('give_greeting', name='Mark') # This will print '/greeting/Mark'

@app.route('/greeting/<name>')
def give_greeting(name):
    return 'Hello, {0}!'.format(name)

这是有利的,因为现在我们可以更改应用程序的URL,而无需更改引用该资源的行。

为什么不总是使用视图函数的名称?

可能会出现以下问题:“为什么我们需要这个额外的层?” 为什么将路径映射到端点,然后将端点映射到视图函数?为什么不跳过这一中间步骤呢?

原因是因为它以这种方式更强大。例如,烧瓶蓝图允许您将应用程序分成多个部分。我可能将所有管理员端资源都放在一个名为“ admin”的蓝图中,而所有用户级资源都放在一个名为“ user”的端点中。

蓝图允许您将它们分成命名空间。例如...

main.py:

from flask import Flask, Blueprint
from admin import admin
from user import user

app = Flask(__name__)
app.register_blueprint(admin, url_prefix='admin')
app.register_blueprint(user, url_prefix='user')

admin.py:

admin = Blueprint('admin', __name__)

@admin.route('/greeting')
def greeting():
    return 'Hello, administrative user!'

user.py:

user = Blueprint('user', __name__)
@user.route('/greeting')
def greeting():
    return 'Hello, lowly normal user!'

请注意,在两个蓝图中,“ / greeting”路由是一个称为“ greeting”的函数。如果我想参考管理员的“ greeting”功能,我不能只说“ greeting”,因为还有一个用户的“ greeting”功能。端点可以通过指定蓝图的名称作为端点的一部分来实现某种命名空间。因此,我可以执行以下操作...

print url_for('admin.greeting') # Prints '/admin/greeting'
print url_for('user.greeting') # Prints '/user/greeting'

1
关于怎么样了url_for根?我发现错误Could not build url for endpoint ''
TomSawyer

我真的很喜欢您的解释,它使我对这些端点的工作原理有了一个很好的了解。但是,既然我已经理解了这个概念,那么我想您会丢失关于端点的一点,特别是在Flask中。如果不指定端点,则url_for()可能由于X或Y原因而更改函数/类的名称(有人重构代码并找到更合适的名称等),从而破坏了函数中的规则。Flask自动生成的端点可帮助您处理url的更改。显式终结点可帮助您处理函数的url更改和名称更改。
IMCoins '19

1
这确实清除了我对Flask端点功能的理解,甚至可能使我对端点的定义一无所知。我也发现了一些错字。您的View函数不应该give_greeting代替my_greeting吗?我什么都没看见my_greeting..
steveohmn '19

23

端点是用于反向查询url规则url_for的名称,默认为视图函数的名称。

小例子:

from flask import Flask, url_for

app = Flask(__name__)

# We can use url_for('foo_view') for reverse-lookups in templates or view functions
@app.route('/foo')
def foo_view():
    pass

# We now specify the custom endpoint named 'bufar'. url_for('bar_view') will fail!
@app.route('/bar', endpoint='bufar')
def bar_view():
    pass

with app.test_request_context('/'):
    print url_for('foo_view')
    print url_for('bufar')
    # url_for('bar_view') will raise werkzeug.routing.BuildError
    print url_for('bar_view')
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.