Flask, URL yönlendirmesinde normal ifadeleri destekliyor mu?


101

Flask'ın int, float ve yol dönüştürücülere sahip olduğunu anlıyorum, ancak geliştirmekte olduğumuz uygulamanın URL'lerinde daha karmaşık modeller var.

Django'da olduğu gibi normal ifadeleri kullanmanın bir yolu var mı?

Yanıtlar:


193

Armin kabul edilen bir cevapla beni yumruk attıysa da, Flask'ta bir normal ifade eşleştiriciyi nasıl uyguladığıma dair kısaltılmış bir örnek göstereceğimi düşündüm, bunun nasıl yapılabileceğine dair çalışan bir örnek istemesi durumunda.

from flask import Flask
from werkzeug.routing import BaseConverter

app = Flask(__name__)

class RegexConverter(BaseConverter):
    def __init__(self, url_map, *items):
        super(RegexConverter, self).__init__(url_map)
        self.regex = items[0]


app.url_map.converters['regex'] = RegexConverter

@app.route('/<regex("[abcABC0-9]{4,6}"):uid>-<slug>/')
def example(uid, slug):
    return "uid: %s, slug: %s" % (uid, slug)


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

bu URL 200: http: // localhost: 5000 / abc0-foo / ile dönmelidir

bu URL 404: http: // localhost: 5000 / abcd-foo / ile dönmelidir


4
Ancak bu, normal ifadelerin derlendiği anlamına mı geliyor yoksa anında değerlendiriliyor mu?
Games Brainiac

1
Görünüşe göre normal ifade doğrudan çalışma zamanında değerlendirilecek. Son birkaç normal ifade kalıbı bellekte saklandığından, bu daha küçük uygulamalar (veya regex'leri birden çok kez yeniden kullanan uygulamalar) için sorunlu olmamalıdır.
bbenne

6
Bu nasıl çalışıyor? Kalıp olarak ayarlandı self.regex, ancak eşleşme nerede oluyor?
Justin

@Justin Eşleşme, Werkzeug'un iç kısımlarında oluyor Burada ve bulamadığım bir kuralın tanımında bir yerde.
AlexLordThorsen

49

İsteğe bağlı ifadelerle eşleşen özel dönüştürücüler bağlayabilirsiniz: Özel Dönüştürücü

from random import randrange
from werkzeug.routing import Rule, Map, BaseConverter, ValidationError

class BooleanConverter(BaseConverter):

    def __init__(self, url_map, randomify=False):
        super(BooleanConverter, self).__init__(url_map)
        self.randomify = randomify
        self.regex = '(?:yes|no|maybe)'

    def to_python(self, value):
        if value == 'maybe':
            if self.randomify:
                return not randrange(2)
            raise ValidationError()
        return value == 'yes'

    def to_url(self, value):
        return value and 'yes' or 'no'

url_map = Map([
    Rule('/vote/<bool:werkzeug_rocks>', endpoint='vote'),
    Rule('/vote/<bool(randomify=True):foo>', endpoint='foo')
], converters={'bool': BooleanConverter})

Ben anlamıyorum to_pythonyok
corvid

17

Ayrıca her tür rotayı yakalama yazabilir ve yöntem içinde karmaşık yönlendirme yapabilirsiniz:

from flask import Flask
app = Flask(__name__)

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

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

Bu, herhangi bir taleple eşleşecektir. Daha fazla ayrıntıya buradan bakın: Tümünü Yakala URL'si .


Bir hatam var, bana bazı ipuçları verir misin? Dosya "/app/catch_all.py", satır 234, <module> @ app.route ('/ <yol: yol>', yöntemler = ['GET']) Dosya "/ usr / local / lib / python2. 7 / dist-packages / flask / app.py ", satır 1080, dekoratör Dosyasında" /usr/local/lib/python2.7/dist-packages/flask/app.py ", satır 64, wrapper_func Dosyasında" / usr / local / lib / python2.7 / dist-packages / flask / app.py ", satır 1051, add_url_rule 'mevcut uç nokta işlevi:% s'% uç nokta) AssertionError: Görünüm işlevi eşlemesi, mevcut bir uç nokta işlevinin üzerine yazıyor: test
kıvılcımı
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.