第七章删除条目后重定向到主页面时产生了不正确的HTTP请求导致405错误

第七章最后通过 delete 视图函数实现删除操作

@app.route('/movie/delete/<int:movie_id>', methods=['POST'])
def delete(movie_id):
    movie = Movie.query.get_or_404(movie_id)
    db.session.delete(movie)
    db.session.commit()
    flash('Item deleted.')
    return redirect(url_for('index'))

对应的 HTML 表单为

<form class="inline-form" method="post" action="{{ url_for('delete', movie_id=movie.id) }}">
    <input class="btn" type="submit" name="delete" value="Delete" onclick="return confirm('Are you sure?')">
</form>

在通过 redirect 重定向到 index.html 时出现了 405 错误,命令行输出如下

127.0.0.1 - - [01/May/2022 09:42:25] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [01/May/2022 09:42:25] "GET /static/images/avatar.png HTTP/1.1" 304 -
127.0.0.1 - - [01/May/2022 09:42:25] "GET /static/images/totoro.gif HTTP/1.1" 304 -
127.0.0.1 - - [01/May/2022 09:42:25] "GET /static/style.css HTTP/1.1" 304 -
127.0.0.1 - - [01/May/2022 09:42:25] "GET /static/favicon.ico HTTP/1.1" 304 -
127.0.0.1 - - [01/May/2022 09:42:27] "POST /movie/delete/12 HTTP/1.1" 302 -
127.0.0.1 - - [01/May/2022 09:42:27] "delete=DeleteGET / HTTP/1.1" 405 -

其中最后一条的请求不是预期中的 GET,而是奇怪的 delete=DeleteGET,而 index 视图函数默认只接受 GET 请求,导致 405 错误。不知道为什么重定向时产生了这样的请求,希望有朋友能指出问题……

已与仓库中对应版本的代码进行了比较,Python 和 flask 的版本分别为 3.10.4 和 2.1.1。

看起来是 Werkzeug 在解析请求的时候把表单值(delete=Delete)识别为 HTTP 方法的一部分了。升级 Werkzeug 到最新版本试试?

pip install -U werkzeug
1 Like

谢谢您抽空回答,我刚刚在 Github 上看到这个条目了(#2397),将 Werkzeug 升级到 2.1.2 后确实解决了问题。

2 Likes