Flask può avere parametri URL opzionali?


258

È possibile dichiarare direttamente un parametro opzionale URL pallone?

Attualmente sto procedendo nel modo seguente:

@user.route('/<userId>')
@user.route('/<userId>/<username>')
def show(userId, username=None):
    pass

Come posso dire direttamente che usernameè facoltativo?

Risposte:


341

Un altro modo è scrivere

@user.route('/<user_id>', defaults={'username': None})
@user.route('/<user_id>/<username>')
def show(user_id, username):
    pass

Ma suppongo che tu voglia scrivere un singolo percorso e contrassegnarlo usernamecome facoltativo? In tal caso, non credo sia possibile.


Problemi con questo metodo quando si fa riferimento a endpoint e url_for?

2
Non che io sappia. Anche i documenti Flask contengono un esempio simile (è necessario scorrere un po 'verso il basso per vederlo).
Audrius Kažukauskas,

1
Puoi provare a installare pip flask_optional_routes. Ho creato un pip per la funzionalità che stai richiedendo in b / c e ne avevo bisogno. Il codice si trova su: github.com/sudouser2010/flask_optional_routes .
sudouser2010

upvoted! se nella tua home page sono presenti più schede in cui ognuna attiva qualcosa come / uno / due / tre / quattro e desideri caricare contenuti diversi sulla stessa pagina senza ricaricare la pagina, dovresti utilizzare un percorso singolo o più percorsi?
PirateApp il

@PirateApp che non può essere realizzato con solo Flask ed è puramente una funzionalità di frontend
qaisjp

183

Quasi lo stesso di Audrius inventato alcuni mesi fa, ma potresti trovarlo un po 'più leggibile con le impostazioni predefinite nell'intestazione della funzione - il modo in cui sei abituato con Python:

@app.route('/<user_id>')
@app.route('/<user_id>/<username>')
def show(user_id, username='Anonymous'):
    return user_id + ':' + username

3
Inoltre, questo funziona se usernamenon è costante. defaults=blocca il valore predefinito in un dizionario.
Kasperhj,

2
Preferisco questo. Dovremmo mantenere il codice il più pulito possibile.
Light.G

Tieni presente che qui c'è un grande avvertimento: se hai più argomenti posizionali e non tutti opzionali, Flask non capirà come costruire correttamente l'URL. Puoi ottenere qualcosa come / page? Arg = foo dove dovrebbe essere / foo / page. La risposta di @Audrius Kažukauskas funziona in quel caso, ma non è così
rgargente,

73

Se stai usando Flask-Restful come me, è anche possibile in questo modo:

api.add_resource(UserAPI, '/<userId>', '/<userId>/<username>', endpoint = 'user')

a quindi nella tua classe di risorse:

class UserAPI(Resource):

  def get(self, userId, username=None):
    pass


11
@app.route('/', defaults={'path': ''})
@app.route('/< path:path >')
def catch_all(path):
    return 'You want path: %s' % path

http://flask.pocoo.org/snippets/57/


3
Dovresti aggiungere qui le informazioni dal link esterno perché se quel link non sarà più valido, la tua risposta sarà danneggiata.
Tomab,

9
@user.route('/<user_id>', defaults={'username': default_value})
@user.route('/<user_id>/<username>')
def show(user_id, username):
   #
   pass

5

Quasi uguale a skornos, ma con dichiarazioni variabili per una risposta più esplicita. Può funzionare con l' estensione Flask-RESTful :

from flask import Flask
from flask_restful import Resource, Api

app = Flask(__name__)
api = Api(app)

class UserAPI(Resource):
    def show(userId, username=None):
    pass

api.add_resource(UserAPI, '/<userId>', '/<userId>/<username>', endpoint='user')

if __name__ == '__main__':
    app.run()

Il add_resourcemetodo consente di passare URL multipli. Ognuno verrà indirizzato alla tua risorsa .


1

So che questo post è davvero vecchio ma ho lavorato su un pacchetto che fa questo chiamato flask_optional_routes. Il codice si trova all'indirizzo: https://github.com/sudouser2010/flask_optional_routes .

from flask import Flask

from flask_optional_routes import OptionalRoutes


app = Flask(__name__)
optional = OptionalRoutes(app)

@optional.routes('/<user_id>/<user_name>?/')
def foobar(user_id, user_name=None):
    return 'it worked!'

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000)

0

Puoi scrivere come mostrato nell'esempio, ma poi ottieni errore di compilazione.

Per risolvere questo problema:

  1. stampa app.url_map () nel tuo root .py
  2. vedi qualcosa come:

<Rule '/<userId>/<username>' (HEAD, POST, OPTIONS, GET) -> user.show_0>

e

<Rule '/<userId>' (HEAD, POST, OPTIONS, GET) -> .show_1>

  1. che nel modello puoi {{ url_for('.show_0', args) }}e{{ url_for('.show_1', args) }}

-6

Da Flask 0.10 non è possibile aggiungere più route a un endpoint. Ma puoi aggiungere un endpoint falso

@user.route('/<userId>')
def show(userId):
   return show_with_username(userId)

@user.route('/<userId>/<username>')
def show_with_username(userId,username=None):
   pass

5
Che cosa? Usando il pallone 0.10.1 qui e posso aggiungere più percorsi a un endpoint bene.
Jaapz,

-8

Penso che tu possa usare Blueprint e questo renderà il tuo codice aspetto migliore e ordinato.

esempio:

from flask import Blueprint

bp = Blueprint(__name__, "example")

@bp.route("/example", methods=["POST"])
def example(self):
   print("example")

Questo non risponde alla domanda.
meyer9
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.