尝试构建无RESTless API时出现Getting Method Not Allowed错误



我正在学习Flask,我发现了各种片段,展示了如何使用SQLAlchemy定义模型、使用Flask-restless定义REST API以及使用Flask-wtf定义表单(我对REST API不太熟悉)。更确切地说,我的灵感来自:

  • 烧瓶不安快速启动(来自医生)
  • 根据模型自动创建WTForms表单(可追溯到2011年)
  • 基本模板的SO问题

然而,我还没能创建一个完全可行的例子。基于您可以在网上找到的比特,我想创建一个具有两个类PersonComputer的模型(一个Person可以与几个Computer相关联)和一个添加新Person的表单。这是我汇编的代码。

布局如下:

test_flask/
├── test_flask.py
├── config.py
└── templates
    └── new_person.html

主文件test_flask.py包含:

from flask import Flask, request, flash, redirect, render_template, url_for
import flask.ext.sqlalchemy
from wtforms.ext.sqlalchemy.orm import model_form
import flask.ext.restless
from flaskext.wtf import Form
# Create the Flask application and the Flask-SQLAlchemy object.
app = Flask(__name__)
app.config.from_object('config')
db = flask.ext.sqlalchemy.SQLAlchemy(app)
# Create the Flask-SQLALchemy models.
class Person(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode, unique=True)
    birth_date = db.Column(db.Date)

class Computer(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode, unique=True)
    vendor = db.Column(db.Unicode)
    purchase_time = db.Column(db.DateTime)
    owner_id = db.Column(db.Integer, db.ForeignKey('person.id'))
    owner = db.relationship('Person', backref=db.backref('computers',
                                                         lazy='dynamic'))
# Create the database tables.
db.create_all()
# Create the Flask-Restless API manager.
manager = flask.ext.restless.APIManager(app, flask_sqlalchemy_db=db)
# Create API endpoints.
manager.create_api(Person, methods=['GET', 'POST', 'DELETE'])
manager.create_api(Computer, methods=['GET'])
# Create a form class for class Person.
PersonForm = model_form(Person, base_class=Form)

@app.route('/')
def hello():
    return 'Hello World'

@app.route("/api/new_person")
def new_person():
    # The new person
    person = Person()
    # Create a form
    form = PersonForm(request.form, person)
    if form.validate_on_submit():
        form.populate_obj(person)
        person.post()
        flash("new person %s inserted updated" % person)
        return redirect(url_for("new_person"))
    return render_template("new_person.html", form=form)
if __name__ == '__main__':
    # start the flask loop
    app.run()

config.py文件包含:

DEBUG = True
WTF_CSRF_SECRET_KEY = 'a random string'
SECRET_KEY = 'you-will-never-guess'
WTF_CSRF_ENABLED = True
SQLALCHEMY_DATABASE_URI = 'sqlite:////tmp/test.db'

模板new_person.html包含:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
  <head>
    <meta http-equiv="content-type" content="application/json">
    <title>New person</title>
  </head>
{% block body %}
    <form action="new_person" method=post class=add-entry>
      <dl>
        <dt>Name:
        <dd>{{form.name}}
        <dt>Birth date:
        <dd>{{form.birth_date}}
        <dd><input type=submit value=submit>
      </dl>
    </form>
{% endblock %}
</html>

我可以在http://127.0.0.1:5000/api/new_person/上看到添加新人的表格,但在提交时出现了"不允许方法"错误。

您正在过帐到new_person路由,但尚未将该路由配置为接受POST请求。默认情况下,只允许使用GETHEAD。将methods参数设置为route()装饰器:

@app.route("/api/new_person", methods=['GET', 'POST'])
def new_person():

请参阅Flask Quickstart的HTTP方法部分。

接下来,如果您希望更改保持不变(例如添加新的Person),则需要提交事务;将新的person对象添加到会话中并提交:

db.session.add(person)
db.session.commit()

请参阅Flask SQLAlchemy选择、插入、删除一章的插入记录部分。

或者,将SQLAlchemy会话设置为自动提交所有更改:

db = flask.ext.sqlalchemy.SQLAlchemy(app, session_options={'autocommit': True})

但是,您仍然需要将新对象添加到会话中。

相关内容

  • 没有找到相关文章

最新更新