Flask含默认参数的URL能否处理POST请求


#1

昨天在微信群里请教了如何向Flask默认参数的URL发送POST请求,不过因为时间太晚最后没有得到解答,现在把问题贴到论坛,希望有大佬能点拨一下。

按Flask文档所述,如果一个URL包含了默认参数,会被301重定向到简单格式的URL。如下方文档代码示例,发送到/users/page/1的请求会被重定向到 /users/,因为重定向过程不保留form数据,所以无法处理POST请求,是不是就意味着 无法向含默认参数的URL发送POST请求了呢? 感觉这个设定不太合理。

作为参考,我的具体使用场景如下:

@app.route('/posts/<id>', defaults={'type': 'wechat'}) 
@app.route('/posts/<str:type>/<id>', methods=['POST', 'GET']) 
def show_users(type, id): 
    pass

post的默认类型为wechat,因为要在该视图内处理表单的提交,所以需要接收POST方法的请求,假如以上所述确实,我向/posts/wechat/1发送的POST请求会被重定向到/posts/1, 这种情况应该怎么解决呢?

Flask 文档中对URL接收默认参数的介绍如下:

Here for example is a definition for a URL that accepts an optional page:

@app.route('/users/', defaults={'page': 1}) 
@app.route('/users/page/<int:page>') 
def show_users(page): 
    pass

This specifies that /users/ will be the URL for page one and /users/page/N will be the URL for page N .

If a URL contains a default value, it will be redirected to its simpler form with a 301 redirect. In the above example, /users/page/1 will be redirected to /users/ . If your route handles GET and POST requests, make sure the default route only handles GET , as redirects can’t preserve form data.

@app.route('/region/', defaults={'id': 1}) 
@app.route('/region/<id>', methods=['GET', 'POST']) 
def region(id): 
    pass

#2

这种问题我昨天遇到过,两个装饰器的url的规则需要保持一致,就是第一个含有默认参数的装饰器也需要加上 str:type这个参数,这样就能正常显示啦

还有帮我回答一下我的问题吧 谢谢


#3

我简单测试了一下,POST 请求不会被重定向。先不管这个重定向行为是否合理,请问你在这里具体要实现的功能是什么?


#5
@app.route('/posts/<id>', defaults={'type': 'wechat'}) 
@app.route('/posts/<str:type>/<id>', methods=['POST', 'GET']) 
def show_post(type, id): 
    pass

要实现的功能是向 posts/wechat/123 这个url发送包含了表单数据的 POST 请求。

按我对文档关于默认参数这一段的理解,这个请求会被重定向到 posts/123 ,但我测试了实际上并没有,不知道是我的理解有问题还是测试用例有问题。


#6

按照我的理解,文档最后一段的意思是:只要不让包含默认值的路由处理 POST 请求,POST 请求就不会被重定向。实际测试也是这样。没必要考虑没发生的问题。