Flask のルーティング

Flask というか Werkzeug のルーティングの挙動が分からない…。

from flask import Flask
app = Flask(__name__)

@app.route('/<user>/')
def user(user):
    print user
    return user

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

これで、http://127.0.0.1/foo/ とやれば、

foo
127.0.0.1 - - [29/Dec/2010 22:01:53] "GET /foo/ HTTP/1.1" 200 -

と表示されるが、

http://127.0.0.1/foo だと

127.0.0.1 - - [29/Dec/2010 22:02:56] "GET /foo HTTP/1.1" 301 -
foo
127.0.0.1 - - [29/Dec/2010 22:02:56] "GET /foo/ HTTP/1.1" 200 -

301 でリダイレクトされる。
ここまでは良い。

from flask import Flask, request
app = Flask(__name__)

@app.route('/<user>/', method=['GET'])
def user(user):
    print request.args
    return user

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

クエリストリングを取得するようにした場合、
http://127.0.0.1/bar/?foo=baz

ImmutableMultiDict([('bar', u'foo')])
127.0.0.1 - - [29/Dec/2010 22:09:41] "GET /bar/?bar=foo HTTP/1.1" 200 -

ちゃんと取れる。


http://127.0.0.1/bar?foo=baz

127.0.0.1 - - [29/Dec/2010 22:09:54] "GET /bar?bar=foo HTTP/1.1" 301 -
ImmutableMultiDict([])
127.0.0.1 - - [29/Dec/2010 22:09:54] "GET /bar/ HTTP/1.1" 200 -

とリダイレクトがかかり、クエリストリングが削除されてしまう。
こういう仕様なの?


ちなみに Pylons の場合、config/routing.py で、

def make_map(config):
    """Create, configure and return the routes Mapper"""
    map = Mapper(directory=config['pylons.paths']['controllers'],
                 always_scan=config['debug'])
    map.minimization = True
    map.explicit = False

    map.connect('/<user>/', controller='index', action='index')

    return app

と map.minimization を True に設定すると、
http://127.0.0.1/foo?bar=baz
http://127.0.0.1/foo/?bar=baz
は同じ結果になる。


追記:以下のようにすれば行けるみたい

from flask import Flask, request
app = Flask(__name__)

@app.route('/<user>/', method=['GET'], strict_slashes=False)
def user(user):
    print request.args
    return user

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