Flask中的“端点”是什么?

问题:Flask中的“端点”是什么?

瓶文档显示

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

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

The Flask documentation shows:

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

What exactly is meant by an “endpoint”?


回答 0

烧瓶路由如何工作

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'

How Flask Routing Works

The entire idea of Flask (and the underlying Werkzeug library) is to map URL paths to some logic that you will run (typically, the “view function”). Your basic view is defined like this:

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

Note that the function you referred to (add_url_rule) achieves the same goal, just without using the decorator notation. Therefore, the following is the same:

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

Let’s say your website is located at ‘www.example.org’ and uses the above view. The user enters the following URL into their browser:

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

The job of Flask is to take this URL, figure out what the user wants to do, and pass it on to one of your many python functions for handling. It takes the path:

/greeting/Mark

…and matches it to the list of routes. In our case, we defined this path to go to the give_greeting function.

However, while this is the typical way that you might go about creating a view, it actually abstracts some extra info from you. Behind the scenes, Flask did not make the leap directly from URL to the view function that should handle this request. It does not simply say…

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

Actually, it there is another step, where it maps the URL to an endpoint:

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"

Basically, the “endpoint” is an identifier that is used in determining what logical unit of your code should handle the request. Normally, an endpoint is just the name of a view function. However, you can actually change the endpoint, as is done in the following example.

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

Now, when Flask routes the request, the logic looks like this:

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"

How You Use the Endpoint

The endpoint is commonly used for the “reverse lookup”. For example, in one view of your Flask application, you want to reference another view (perhaps when you are linking from one area of the site to another). Rather than hard-code the URL, you can use url_for(). Assume the following

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

This is advantageous, as now we can change the URLs of our application without needing to change the line where we reference that resource.

Why not just always use the name of the view function?

One question that might come up is the following: “Why do we need this extra layer?” Why map a path to an endpoint, then an endpoint to a view function? Why not just skip that middle step?

The reason is because it is more powerful this way. For example, Flask Blueprints allow you to split your application into various parts. I might have all of my admin-side resources in a blueprint called “admin”, and all of my user-level resources in an endpoint called “user”.

Blueprints allow you to separate these into namespaces. For example…

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!'

Note that in both blueprints, the ‘/greeting’ route is a function called “greeting”. If I wanted to refer to the admin “greeting” function, I couldn’t just say “greeting” because there is also a user “greeting” function. Endpoints allow for a sort of namespacing by having you specify the name of the blueprint as part of the endpoint. So, I could do the following…

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

回答 1

端点是用于反向查询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')

Endpoint is the name used to reverse-lookup the url rules with url_for and it defaults to the name of the view function.

Small example:

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