Что такое «конечная точка» во Flask?

125

В документации 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

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

Fuziang
источник

Ответы:

267

Как работает Flask Routing

Вся идея 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-адреса нашего приложения без необходимости изменять строку, в которой мы ссылаемся на этот ресурс.

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

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

Причина в том, что так он более мощный. Например, Flask Blueprints позволяет разделить приложение на несколько частей. У меня могут быть все мои административные ресурсы в схеме под названием «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!'

Обратите внимание на то, что в обоих схемах маршрут «/ приветствие» является функцией, называемой «приветствием». Если бы я хотел обратиться к функции «приветствия» администратора, я не мог бы просто сказать «приветствие», потому что есть также функция «приветствие» пользователя. Конечные точки допускают своего рода пространство имен, если вы указываете имя схемы как часть конечной точки. Итак, я мог сделать следующее ...

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
1
Это действительно проясняет мое понимание функциональности конечной точки Flask и, возможно, даже определения конечной точки в целом. Также я обнаружил опечатку. Разве ваша функция просмотра не должна быть give_greetingвместо my_greeting? Я my_greetingнигде не увижу ..
steveohmn
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')
plaes
источник