【发布时间】:2016-07-18 14:19:24
【问题描述】:
我正在学习 Flask,我发现了各种 sn-ps,它们展示了如何使用 SQLAlchemy 定义模型、使用 Flask-restless 定义 REST API 以及使用 Flask-wtf 定义表单(我对 REST API 不是很熟悉)。更准确地说,我的灵感来自:
- Flask-restless Quickstart(来自文档)
- Automatically create a WTForms Form from model(可追溯到 2011 年)
- This SO question 用于基本模板
但是我无法创建一个完整的工作示例。基于您可以在网上找到的位,我想创建一个具有 2 个类 Person 和 Computer 的模型(Person 可以与多个 Computers 相关联)和一个添加新 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/ 看到添加新人的表单,但在提交时出现“方法不允许”错误。
【问题讨论】:
-
@Martijn Pieters 我将链接添加到我遵循的教程中(我不使用
WTF-Alchemy这应该会更好一些)。我的问题恰恰是将所有的 sn-ps 粘合在一起。 -
我的直觉是
person.post()方法(我相信它是插入新Person的方法)实际上从未被调用...我试图更改@987654345 的形式@ 到api/person但没有成功。 -
其实
person.post()是从哪里来的?这不会将新实例添加到您的数据库中.. -
我从here复制了这部分(并将
model重命名为person)但我意识到他们实际上使用'put()'......我不认为改变任何事情,因为这段代码永远不会被调用。 -
你确定代码永远不会被调用吗?虽然我怀疑您需要告诉表单
id字段不是表单有效所必需的。
标签: python flask flask-sqlalchemy flask-wtforms flask-restless