Что такое "конечная точка" в 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

Что конкретно подразумевается под "конечной точкой"?

Ответ 1

Как работает работа с флягами

Вся идея 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 "my_greeting")

Собственно, это еще один шаг, когда он сопоставляет URL-адрес конечной точке:

URL (http://www.example.org/greeting/Mark) should be handled by Endpoint "my_greeting".
Requests to Endpoint "my_greeting" should be handled by View Function "my_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 "my_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-адреса нашего приложения, не требуя изменения строки, на которой мы ссылаемся на этот ресурс.

Почему бы просто не использовать имя функции просмотра?

Один вопрос, который может возникнуть, следующий: "Зачем нам этот дополнительный слой?" Зачем сопоставлять путь к конечной точке, а затем конечную точку для функции просмотра? Почему бы просто не пропустить этот средний шаг?

Причина в том, что она более мощная. Например, Flask Blueprints позволяет разбить приложение на различные части. Я мог бы использовать все мои ресурсы админки в проекте под названием "admin" и всех моих ресурсов пользовательского уровня в конечной точке, называемой "пользователь".

Чертежи позволяют разделить их на пространства имен. Например...

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' - это функция, называемая "приветствие". Если бы я хотел обратиться к функции "приветствия" администратора, я не мог просто сказать "приветствие", потому что есть также функция "приветствия" пользователя. Конечные точки допускают своего рода пространство имен путем указания имени плана как части конечной точки. Итак, я мог бы сделать следующее...

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

Ответ 2

Конечная точка - это имя, используемое для обратного поиска правил 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')