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

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

Ответы:


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')
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.