Bisakah Flask memiliki parameter URL opsional?

258

Apakah mungkin untuk secara langsung mendeklarasikan parameter opsional URL flask?

Saat ini saya sedang melanjutkan cara berikut:

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

Bagaimana saya bisa langsung mengatakan bahwa usernameitu opsional?

Noor
sumber

Jawaban:

341

Cara lain adalah menulis

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

Tapi saya kira Anda ingin menulis satu rute dan tandai usernamesebagai opsional? Jika itu masalahnya, saya pikir itu tidak mungkin.

Audrius Kažukauskas
sumber
Adakah masalah dalam menggunakan metode ini saat merujuk titik akhir dan url_for?
2
Tidak yang saya tahu. Bahkan dokumen Flask berisi contoh serupa (Anda perlu sedikit gulir ke bawah untuk melihatnya).
Audrius Kažukauskas
1
Anda dapat mencoba menginstal pip flask_optional_routes. Saya membuat pip untuk fungsionalitas yang Anda minta b / c saya membutuhkannya juga. Kode ini terletak di: github.com/sudouser2010/flask_optional_routes .
sudouser2010
terbalik! jika Anda memiliki banyak tab pada halaman beranda tempat masing-masing memicu sesuatu seperti / satu / dua / tiga / empat dan Anda ingin memuat konten yang berbeda pada halaman yang sama tanpa memuat ulang halaman, haruskah Anda menggunakan satu rute atau beberapa rute?
PirateApp
@PirateApp yang tidak dapat dicapai hanya dengan Flask dan murni fitur frontend
qaisjp
183

Hampir sama dengan Audrius yang dibuat beberapa bulan yang lalu, tetapi Anda mungkin menemukan itu sedikit lebih mudah dibaca dengan default di kepala fungsi - cara Anda terbiasa dengan python:

@app.route('/<user_id>')
@app.route('/<user_id>/<username>')
def show(user_id, username='Anonymous'):
    return user_id + ':' + username
Monggol
sumber
3
Juga, ini berfungsi jika usernametidak konstan. defaults=membekukan nilai default di kamus.
kasperhj
2
Saya lebih suka yang ini. Kita harus menjaga kode sebersih mungkin.
Light.G
Ingatlah bahwa ada peringatan besar di sini: jika Anda memiliki beberapa argumen posisi dan tidak semuanya opsional, labu tidak akan mengerti cara membuat URL dengan benar. Anda bisa mendapatkan sesuatu seperti / halaman? Arg = foo di mana seharusnya / foo / halaman. @Audrius Kažukauskas menjawab berfungsi dalam kasus itu, tetapi ini tidak
rgargente
73

Jika Anda menggunakan Flask-Restful seperti saya, juga dimungkinkan dengan cara ini:

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

a kemudian di kelas Sumber Daya Anda:

class UserAPI(Resource):

  def get(self, userId, username=None):
    pass
skornos
sumber
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
sumber
3
Anda harus menambahkan di sini info dari tautan eksternal karena jika tautan itu tidak lagi valid, jawaban Anda akan rusak.
tomab
9
@user.route('/<user_id>', defaults={'username': default_value})
@user.route('/<user_id>/<username>')
def show(user_id, username):
   #
   pass
aman kumar
sumber
5

Hampir sama dengan skornos, tetapi dengan deklarasi variabel untuk jawaban yang lebih eksplisit. Ini dapat bekerja dengan ekstensi 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()

The add_resourceMetode memungkinkan kelipatan lulus URL. Masing-masing akan diarahkan ke Sumber Daya Anda .

yoelvis
sumber
1

Saya tahu posting ini benar-benar tua tetapi saya mengerjakan sebuah paket yang melakukan ini disebut flask_optional_routes. Kode ini terletak di: 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
sumber
0

Anda dapat menulis seperti yang Anda tunjukkan dalam contoh, tetapi Anda tidak mendapatkan build-error.

Untuk memperbaiki ini:

  1. cetak app.url_map () di Anda root .py
  2. Anda melihat sesuatu seperti:

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

dan

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

  1. dari pada template yang Anda bisa {{ url_for('.show_0', args) }}dan{{ url_for('.show_1', args) }}
lov3catch
sumber
-6

Karena Flask 0.10 Anda tidak dapat menambahkan beberapa rute ke satu titik akhir. Tetapi Anda dapat menambahkan titik akhir palsu

@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
sumber
5
Apa? Menggunakan labu 0.10.1 di sini dan saya dapat menambahkan beberapa rute ke satu titik akhir dengan baik.
jaapz
-8

Saya pikir Anda dapat menggunakan Blueprint dan itu akan membuat kode Anda terlihat lebih baik dan rapi.

contoh:

from flask import Blueprint

bp = Blueprint(__name__, "example")

@bp.route("/example", methods=["POST"])
def example(self):
   print("example")
Def Putra
sumber
Ini tidak menjawab pertanyaan.
meyer9