¿Puede Flask tener parámetros de URL opcionales?

258

¿Es posible declarar directamente un parámetro opcional de URL de matraz?

Actualmente estoy procediendo de la siguiente manera:

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

¿Cómo puedo decir directamente que usernamees opcional?

Noor
fuente

Respuestas:

341

Otra forma es escribir

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

Pero supongo que quieres escribir una sola ruta y marcarla usernamecomo opcional. Si ese es el caso, no creo que sea posible.

Audrius Kažukauskas
fuente
¿Algún problema al usar este método al hacer referencia a puntos finales y url_for?
2
No que yo sepa. Incluso los documentos de Flask contienen un ejemplo similar (debe desplazarse un poco hacia abajo para verlo).
Audrius Kažukauskas
1
Puedes probar pip install flask_optional_routes. Creé un pip para la funcionalidad que está solicitando b / c. También lo necesitaba. El código se encuentra en: github.com/sudouser2010/flask_optional_routes .
sudouser2010
¡Votado! si tiene varias pestañas en su página de inicio donde cada una activa algo como / uno / dos / tres / cuatro y desea cargar contenido diferente en la misma página sin volver a cargar la página, ¿debería usar una ruta única o múltiples rutas?
PirateApp
@PirateApp que no se puede lograr con solo Flask y es puramente una función de interfaz de
usuario
183

Casi lo mismo que Audrius cocinó hace unos meses, pero puede que le resulte un poco más legible con los valores predeterminados en el cabezal de la función, la forma en que está acostumbrado con python:

@app.route('/<user_id>')
@app.route('/<user_id>/<username>')
def show(user_id, username='Anonymous'):
    return user_id + ':' + username
magnate
fuente
3
Además, esto funciona si usernameno es constante. defaults=congela el valor predeterminado en un diccionario.
kasperhj
2
Prefiero éste. Deberíamos mantener el código lo más limpio posible.
Light.G
Tenga en cuenta que hay una gran advertencia aquí: si tiene múltiples argumentos posicionales y no todos son opcionales, el matraz no entenderá cómo construir la URL correctamente. Puede obtener algo como / page? Arg = foo donde debería estar / foo / page. La respuesta de @Audrius Kažukauskas funciona en ese caso, pero esto no
rgargente
73

Si está utilizando Flask-Restful como yo, también es posible de esta manera:

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

un entonces en su clase de recursos:

class UserAPI(Resource):

  def get(self, userId, username=None):
    pass
skornos
fuente
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/

Sona
fuente
3
Debe agregar aquí la información del enlace externo porque si ese enlace ya no será válido, su respuesta se dañará.
tomab
9
@user.route('/<user_id>', defaults={'username': default_value})
@user.route('/<user_id>/<username>')
def show(user_id, username):
   #
   pass
aman kumar
fuente
5

Casi lo mismo que skornos, pero con declaraciones variables para una respuesta más explícita. Puede funcionar con la extensión 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()

El add_resourcemétodo permite pasar múltiples URL. Cada uno se enrutará a su Recurso .

yoelvis
fuente
1

Sé que esta publicación es muy antigua, pero trabajé en un paquete que hace esto llamado flask_optional_routes. El código se encuentra en: 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)
sudouser2010
fuente
0

Puede escribir como muestra en el ejemplo, pero luego obtiene un error de compilación.

Para arreglar esto:

  1. imprima app.url_map () en su raíz .py
  2. ves algo como:

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

y

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

  1. que en la plantilla que puedas {{ url_for('.show_0', args) }}y{{ url_for('.show_1', args) }}
lov3catch
fuente
-6

Desde Flask 0.10 no puede agregar múltiples rutas a un punto final. Pero puedes agregar puntos finales falsos

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

@user.route('/<userId>/<username>')
def show_with_username(userId,username=None):
   pass
Sergey Bargamon
fuente
55
¿Qué? Usando el matraz 0.10.1 aquí y puedo agregar múltiples rutas a un punto final muy bien.
jaapz
-8

Creo que puede usar Blueprint y eso hará que su código se vea mejor y ordenado.

ejemplo:

from flask import Blueprint

bp = Blueprint(__name__, "example")

@bp.route("/example", methods=["POST"])
def example(self):
   print("example")
Def Putra
fuente
Esto no responde la pregunta.
meyer9