URL-Routing-Konflikte für statische Dateien im Flask-Dev-Server

7

Ich möchte eine URL-Regel mit drei variablen Komponenten definieren, wie:

%Vor%

Aber ich finde, dass der Entwicklungsserver solche Regeln auswertet, bevor er versucht, nach statischen Dateien zu suchen. So etwas wie:

%Vor%

wird von meiner URL-Regel abgefangen und nicht an den integrierten statischen Dateihandler weitergeleitet. Gibt es eine Möglichkeit, den Entwicklungsserver dazu zu zwingen, zuerst nach statischen Dateien zu suchen?

P.S. Dies ist nur dann ein Problem, wenn die Regel mehr als zwei variable Komponenten enthält.

    
petrus-jvrensburg 16.06.2013, 15:48
quelle

3 Antworten

16

Dies ist eine Werkzeugroutenoptimierungsfunktion. Siehe Map.add , Map.update und Rule.match_compare_key :

%Vor%

Es gibt self.arguments - aktuelle Argumente, self._weights - Pfadtiefe.

Für '/<var_1>/<var_2>/<var3>/' haben wir (True, -3, [(1, 100), (1, 100), (1, 100)]) . Es gibt (1, 100) - Standard-String-Argument mit maximaler Länge 100.

Für '/static/<path:filename>' haben wir (True, -2, [(0, -6), (1, 200)]) . Es gibt (0, 1) - Pfad nicht Argument String Länge static , (1, 200) - Pfad String Argument maximale Länge 200.

Ich finde also keine schöne Möglichkeit, die eigene Map Implementierung für Flask.url_map zu setzen oder die Priorität für die Mapregel festzulegen. Lösungen:

  1. Setup Flask -Anwendung als app = Flask(static_path='static', static_url_path='/more/then/your/max/variables/path/depth/static') .
  2. Ändern Sie @app.route('/<var_1>/<var_2>/<var3>/') in @app.route('/prefix/<var_1>/<var_2>/<var3>/') .
  3. Einen eigenen Konverter hinzufügen und als @app.route('/<no_static:var_1>/<var_2>/<var3>/') verwenden.
  4. Importieren Sie werkzeug.routing , erstellen Sie eine eigene Kartenimplementierung, ändern Sie werkzeug.routing.Map in eine eigene Implementierung, importieren Sie flask .
  5. Verwenden Sie den Server wie bei der Produktion.
tbicr 17.06.2013, 11:36
quelle
6

Also, wie tbicr es ausdrückte, ist dieses Verhalten tief in Werkzeug verankert, und es gibt nicht wirklich eine elegante Art, es von Flask aus zu handhaben. Der beste Workaround, den ich mir vorstellen kann, ist:

Definieren Sie einen komplementären statischen Dateihandler wie:

%Vor%

Hier ist app.config['STATIC_FOLDER'] der vollständige Pfad zum statischen Ordner auf dem Computer, auf dem die Anwendung ausgeführt wird.

Nun fängt dieser Handler Dinge wie /static/images/img.jpg ab und lässt meine Ansicht mit den drei variablen Komponenten allein.

    
petrus-jvrensburg 17.06.2013 14:01
quelle
3

Eine Möglichkeit, dies zu umgehen, besteht darin, den Regelsortieralgorithmus zu umgehen, indem Sie die Methode match_compare_key() der registrierten Regel spoofieren. Beachten Sie, dass dieser Hack nur mit Routen funktioniert, die direkt mit app.route() (dem Flask-Objekt) registriert wurden, nicht mit Blueprints. Die Routen von Blueprints werden nur dann zur globalen URL-Map hinzugefügt, wenn sich die Blueprint-Registrierung in der Haupt-App befindet. Dadurch wird es schwierig, die generierten Regeln zu ändern.

%Vor%

Beachten Sie, dass die resultierende gefälschte Funktion in diesem Fall nicht an das Regelobjekt gebunden ist. Beim Aufruf von rule.match_compare_key() erhält die Funktion daher kein self -Argument. Wenn Sie die Funktion ordnungsgemäß binden möchten, tun Sie dies stattdessen:

%Vor%

Wir können das oben genannte mit einem Decorator verallgemeinern

%Vor%

Der gleiche Hack wurde als ein Kontextmanager implementiert.

%Vor%     
mike_e 25.02.2014 08:22
quelle

Tags und Links