You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>

错误原因

  1. 表单提交目标路由不支持POST方法:add.html中表单action="lista"会向/lista发送POST请求,但main.py中/lista路由默认仅支持GET方法,触发Method Not Allowed错误。
  2. 重定向指向外部URL:处理POST请求后重定向到外部地址,不符合内部路由逻辑,且易引发环境不一致问题。
  3. 列表路由未传递数据给模板:/lista路由未查询数据库中的联系人数据,模板中{% for e in contatos %}会因变量未定义报错。
  4. 路由装饰器格式不规范:@ 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 04:02:20