Flask注册功能遇Method Not Allowed错误,请求URL方法不被允许
Flask注册联系人出现Method Not Allowed错误的解决方法
问题描述
搭建的网站在注册新联系人时,页面弹出“Method Not Allowed The method is not allowed for the requested URL”错误页面。相关代码文件如下:
main.py
from flask import Flask, render_template, redirect, request from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///bancodados.db' db = SQLAlchemy(app) class Contato(db.Model): id = db.Column('id', db.Integer, primary_key=True, autoincrement=True) nome = db.Column(db.String(100)) email = db.Column(db.String(100)) def __init__(self, nome, email): self.nome = nome self.email = email @ app.route('/', methods=['GET', 'POST']) def home(): if request.method == 'POST': contato = Contato(request.form['nome'], request.form['email']) db.session.add(contato) db.session.commit() return redirect('https://salvacontato.rj.r.appspot.com/lista') return render_template('add.html') @ app.route('/lista') def lista(): return render_template('lista.html') if __name__ == "__main__": db.create_all() app.run(debug=True)
add.html
<!DOCTYPE html> <html lang="pt-BR"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Registrar Contato</title> <style> #log { top: 50%; left: 50%; transform: translate(-50%, -50%); padding: 50px; position: absolute; color: white; background-color: rgba(0, 0, 0, 0.808); border-radius: 30px; font-family: sans-serif; } body { background-image: linear-gradient(25deg, rgb(167, 167, 245), rgb(86, 86, 255)); } input { padding: 13px; outline: none; } button { background-color: dodgerblue; border: none; border-radius: 15px; padding: 15px; width: 100%; } </style> </head> <body> <div id="log"> <h2>Registrar Contato</h2> <form action="lista" method="POST"> <input type="text" name="nome" id="nome" placeholder="Nome do Contato"> <br><br> <input type="text" name="email" id="email" placeholder="Email do Contato"> <br><br> <button type="submit">Enviar</button> </form> </div> </body> </html>
lista.html
<!DOCTYPE html> <html lang="pt-BR"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Contatos</title> </head> <body> <h1>Lista de contatos</h1> <a href="/">Adicionar Contato</a> <table> <thead> <tr> <th>Nome</th> <th>Email</th> </tr> </thead> <tbody> {% for e in contatos %} <tr> <td>{{e.nome}}</td> <td>{{e.email}}</td> </tr> {% endfor %} </tbody> </table> </body> </html>
错误原因
- 表单提交目标路由不支持POST方法:add.html中表单
action="lista"会向/lista发送POST请求,但main.py中/lista路由默认仅支持GET方法,触发Method Not Allowed错误。 - 重定向指向外部URL:处理POST请求后重定向到外部地址,不符合内部路由逻辑,且易引发环境不一致问题。
- 列表路由未传递数据给模板:
/lista路由未查询数据库中的联系人数据,模板中{% for e in contatos %}会因变量未定义报错。 - 路由装饰器格式不规范:
@ app.route存在空格,虽Flask可能兼容,但属于不规范写法。
修复步骤
1. 修改表单提交目标
将add.html中的表单action改为/,让表单提交到支持POST的根路由:
<form action="/" method="POST">
2. 修正重定向地址
将main.py中的重定向改为内部路由:
return redirect('/lista')
3. 完善列表路由的数据查询
修改main.py中的lista函数,查询所有联系人并传递给模板:
@app.route('/lista') def lista(): contatos = Contato.query.all() return render_template('lista.html', contatos=contatos)
4. 规范路由装饰器格式
去掉装饰器中的空格,将@ app.route改为@app.route:
@app.route('/', methods=['GET', 'POST']) def home(): # ... 代码保持不变 @app.route('/lista') def lista(): # ... 代码保持不变
5. 适配Flask上下文要求(可选)
针对Flask 2.0+版本,修改数据库初始化代码,避免上下文错误:
if __name__ == "__main__": with app.app_context(): db.create_all() app.run(debug=True)
修复后的完整代码
main.py
from flask import Flask, render_template, redirect, request from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///bancodados.db' db = SQLAlchemy(app) class Contato(db.Model): id = db.Column('id', db.Integer, primary_key=True, autoincrement=True) nome = db.Column(db.String(100)) email = db.Column(db.String(100)) def __init__(self, nome, email): self.nome = nome self.email = email @app.route('/', methods=['GET', 'POST']) def home(): if request.method == 'POST': contato = Contato(request.form['nome'], request.form['email']) db.session.add(contato) db.session.commit() return redirect('/lista') return render_template('add.html') @app.route('/lista') def lista(): contatos = Contato.query.all() return render_template('lista.html', contatos=contatos) if __name__ == "__main__": with app.app_context(): db.create_all() app.run(debug=True)
add.html
<!DOCTYPE html> <html lang="pt-BR"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Registrar Contato</title> <style> #log { top: 50%; left: 50%; transform: translate(-50%, -50%); padding: 50px; position: absolute; color: white; background-color: rgba(0, 0, 0, 0.808); border-radius: 30px; font-family: sans-serif; } body { background-image: linear-gradient(25deg, rgb(167, 167, 245), rgb(86, 86, 255)); } input { padding: 13px; outline: none; } button { background-color: dodgerblue; border: none; border-radius: 15px; padding: 15px; width: 100%; } </style> </head> <body> <div id="log"> <h2>Registrar Contato</h2> <form action="/" method="POST"> <input type="text" name="nome" id="nome" placeholder="Nome do Contato"> <br><br> <input type="text" name="email" id="email" placeholder="Email do Contato"> <br><br> <button type="submit">Enviar</button> </form> </div> </body> </html>
lista.html
保持原代码不变即可。
内容的提问来源于stack exchange,提问作者M. Eleotério
相关产品推荐
相关产品推荐

