有问题的代码:
from flask import Blueprint, render_template, abort
from flask.ext.wtf import Form
import os
from jinja2 import TemplateNotFound
from models import Member
from wtforms.ext.sqlalchemy.orm import model_form
@simple_page.route('/register')
def register():
form = model_form(Member, Form)
return render_template('register.html', form=form, name="bad")
class Member(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False)
email = db.Column(db.String(50), nullable=False, unique=True)
在我看来:
<p class="txt11 colorb">
{{ form.name }}
</p>
这会输出<UnboundField(TextField, (), {u'default': None, u'filters': [], u'validators': [<wtforms.validators.Required object at 0x7f62f59b5590>, <wtforms.validators.Length object at 0x7f62f59b55d0>]})>
,而不是实际字段。如何使用wtform获得实际的表单/字段?
答案 0 :(得分:10)
您将表单类而不是表单实例传递给模板。 model_form
方法动态生成一个新类,可以像任何其他表单子类一样重复使用,扩展和使用。在视图的每次运行中生成此表单类也非常不必要,因此您可以将此调用移到视图之外。
您传递一个未实例化的类也是您获得与UnboundField相关的奇怪行为的原因(这是WTForms处理声明性字段实例化的方式)
修复很简单:
MemberForm = model_form(Member, base_class=Form)
@simple_page.route('/register')
def register():
form = MemberForm(name=u'bad')
return render_template('register.html', form=form)
答案 1 :(得分:2)
你需要做更多的工作:
{{ form.name.label }} : {{ form.name()|safe }}
或者,您可以使用此handy snippet:
{% macro render_field(field) %}
<dt>{{ field.label }}
<dd>{{ field(**kwargs)|safe }}
{% if field.errors %}
<ul class=errors>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</dd>
{% endmacro %}
当然,调整呈现的HTML。将该文件保存在templates
目录中的某个位置,然后保存在主模板中。这是formhelpers.html
:
{% from "formhelpers.html" import render_field %}
<form method=post action="/register">
<dl>
{{ render_field(form.name) }}
{{ render_field(form.email) }}
</dl>
<p><input type=submit value=Register>
</form>
答案 2 :(得分:1)
我知道这已经很老了,但我有同样的问题,我想分享我的期货需求解决方案。
我还得到了#34; UnboundField&#34;呈现的html。在与代码斗争后,我发现我正在使用:
from wtforms import Form
它看起来不错,但在使用Flask时我必须这样做:
from flask.ext.wtf import Form
解决了我的问题。希望它有所帮助