Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
210 views
in Technique[技术] by (71.8m points)

python - URL routing conflicts for static files in Flask dev server

I want to define a url rule with three variable components, like:

@app.route('/<var_1>/<var_2>/<var3>/')

But I find that the development server evaluates such rules before trying to match for static files. So anything like:

/static/images/img.jpg

will be caught by my url rule, rather than being forwarded to the built-in static file handler. Is there a way to force the development server to match for static files first?

P.S. This is only an issue if the rule has more than two variable components.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is werkzeug route optimization feature. See Map.add, Map.update and Rule.match_compare_key:

def match_compare_key(self):
    """The match compare key for sorting.

    Current implementation:

    1. rules without any arguments come first for performance
    reasons only as we expect them to match faster and some
    common ones usually don't have any arguments (index pages etc.)
    2. The more complex rules come first so the second argument is the
    negative length of the number of weights.
    3. lastly we order by the actual weights.

    :internal:
    """
    return bool(self.arguments), -len(self._weights), self._weights

There are self.arguments - current arguments, self._weights - path depth.

For '/<var_1>/<var_2>/<var3>/' we have (True, -3, [(1, 100), (1, 100), (1, 100)]). There are (1, 100) - default string argument with max length 100.

For '/static/<path:filename>' we have (True, -2, [(0, -6), (1, 200)]). There are (0, 1) - path non argument string length static, (1, 200) - path string argument max length 200.

So I don't find any beautiful way to set own Map implementation for Flask.url_map or set priority for map rule. Solutions:

  1. Setup Flask application as app = Flask(static_path='static', static_url_path='/more/then/your/max/variables/path/depth/static').
  2. Change @app.route('/<var_1>/<var_2>/<var3>/') to @app.route('/prefix/<var_1>/<var_2>/<var3>/').
  3. Add own converter and use as @app.route('/<no_static:var_1>/<var_2>/<var3>/').
  4. Import werkzeug.routing, create own map implementation, change werkzeug.routing.Map to own implementation, import flask.
  5. Use server as on production.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...