Come funziona il Flask Routing
L'intera idea di Flask (e della libreria Werkzeug sottostante) è quella di mappare i percorsi URL su una logica che verrà eseguita (in genere, la "funzione di visualizzazione"). La vista di base è definita in questo modo:
@app.route('/greeting/<name>')
def give_greeting(name):
return 'Hello, {0}!'.format(name)
Si noti che la funzione a cui si fa riferimento (add_url_rule) raggiunge lo stesso obiettivo, semplicemente senza usare la notazione del decoratore. Pertanto, il seguente è lo stesso:
# 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)
Supponiamo che il tuo sito Web si trovi in "www.example.org" e utilizzi la vista sopra. L'utente inserisce il seguente URL nel proprio browser:
http://www.example.org/greeting/Mark
Il compito di Flask è prendere questo URL, capire cosa vuole fare l'utente e passarlo a una delle tue numerose funzioni Python per la gestione. Prende il percorso :
/greeting/Mark
... e lo abbina all'elenco dei percorsi. Nel nostro caso, abbiamo definito questo percorso per passare alla give_greetingfunzione.
Tuttavia, mentre questo è il modo tipico in cui potresti creare una vista, in realtà estrae alcune informazioni extra da te. Dietro le quinte, Flask non ha fatto il salto direttamente dall'URL alla funzione di visualizzazione che dovrebbe gestire questa richiesta. Non dice semplicemente ...
URL (http://www.example.org/greeting/Mark) should be handled by View Function (the function "give_greeting")
In realtà, c'è un altro passaggio, in cui associa l'URL a un 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"
Fondamentalmente, "endpoint" è un identificatore utilizzato per determinare quale unità logica del codice deve gestire la richiesta . Normalmente, un endpoint è solo il nome di una funzione di visualizzazione. Tuttavia, è possibile modificare effettivamente l'endpoint, come nell'esempio seguente.
@app.route('/greeting/<name>', endpoint='say_hello')
def give_greeting(name):
return 'Hello, {0}!'.format(name)
Ora, quando Flask indirizza la richiesta, la logica appare così:
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"
Come si utilizza l'endpoint
L'endpoint è comunemente usato per la "ricerca inversa". Ad esempio, in una vista dell'applicazione Flask, si desidera fare riferimento a un'altra vista (forse quando si collega da un'area del sito a un'altra). Anziché codificare l'URL, è possibile utilizzare url_for(). Supponi quanto segue
@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)
Questo è vantaggioso, poiché ora possiamo cambiare gli URL della nostra applicazione senza dover cambiare la linea in cui facciamo riferimento a quella risorsa.
Perché non usare sempre sempre il nome della funzione di visualizzazione?
Una domanda che potrebbe sorgere è la seguente: "Perché abbiamo bisogno di questo ulteriore livello?" Perché mappare un percorso a un endpoint, quindi un endpoint a una funzione di visualizzazione? Perché non saltare quel passaggio intermedio?
Il motivo è perché è più potente in questo modo. Ad esempio, i modelli Flask consentono di dividere l'applicazione in varie parti. Potrei avere tutte le mie risorse lato amministratore in un progetto chiamato "admin" e tutte le mie risorse a livello di utente in un endpoint chiamato "utente".
I progetti consentono di separarli in spazi dei nomi. Per esempio...
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!'
Si noti che in entrambi i progetti, il percorso '/ saluto' è una funzione chiamata "saluto". Se volessi fare riferimento alla funzione "saluto" dell'amministratore, non potrei semplicemente dire "saluto" perché esiste anche una funzione "saluto" dell'utente. Gli endpoint consentono una sorta di spazio dei nomi specificando il nome del progetto come parte dell'endpoint. Quindi, potrei fare quanto segue ...
print url_for('admin.greeting') # Prints '/admin/greeting'
print url_for('user.greeting') # Prints '/user/greeting'
url_forper root? HoCould not build url for endpoint ''