J'ai une application Web complexe basée sur Flask. Il y a beaucoup de fichiers séparés avec des fonctions d'affichage. Leurs URL sont définies avec le décorateur @app.route('/...')
. Existe-t-il un moyen d’obtenir une liste de tous les itinéraires déclarés dans l’application? Peut-être y a-t-il une méthode que je peux appeler sur l'objet app
?
Réponses
Trop de publicités?Toutes les routes d'une application sont stockés sur app.url_map
qui est une instance de l' werkzeug.routing.Map
. Vous pouvez effectuer une itération sur l' Rule
des occurrences à l'aide de l' iter_rules
méthode:
from flask import Flask, render_template, url_for
app = Flask(__name__)
@app.route("/site-map")
def site_map():
links = []
for rule in app.url_map.iter_rules():
# Filter out rules we can't navigate to in a browser
# and rules that require parameters
if "GET" in rule.methods and len(rule.defaults) >= len(rule.arguments):
url = url_for(rule.endpoint)
links.append((url, rule.endpoint))
# links is now a list of url, endpoint tuples
Voir Affichage des liens vers de nouvelles pages web créé pour un peu plus d'informations.
Je crée une méthode d'assistance sur mon manage.py
:
@manager.command
def list_routes():
import urllib
output = []
for rule in app.url_map.iter_rules():
options = {}
for arg in rule.arguments:
options[arg] = "[{0}]".format(arg)
methods = ','.join(rule.methods)
url = url_for(rule.endpoint, **options)
line = urllib.unquote("{:50s} {:20s} {}".format(rule.endpoint, methods, url))
output.append(line)
for line in sorted(output):
print line
Il résout l'argument manquant en construisant un ensemble d'options factices. La sortie ressemble à:
CampaignView:edit HEAD,OPTIONS,GET /account/[account_id]/campaigns/[campaign_id]/edit
CampaignView:get HEAD,OPTIONS,GET /account/[account_id]/campaign/[campaign_id]
CampaignView:new HEAD,OPTIONS,GET /account/[account_id]/new
Puis pour le lancer:
python manage.py list_routes
Pour plus d'informations sur manage.py checkout: http://flask-script.readthedocs.org/en/latest/
Semblable à la réponse de Jonathan, j'ai choisi de le faire à la place. Je ne vois pas l'intérêt d'utiliser url_for car cela casserait si vos arguments ne sont pas des chaînes, par exemple float
@manager.command
def list_routes():
import urllib
output = []
for rule in app.url_map.iter_rules():
methods = ','.join(rule.methods)
line = urllib.unquote("{:50s} {:20s} {}".format(rule.endpoint, methods, rule))
output.append(line)
for line in sorted(output):
print(line)