问题
code in question:
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)
and in my view:
<p class="txt11 colorb">
{{ form.name }}
</p>
this outputs <UnboundField(TextField, (), {u'default': None, u'filters': [], u'validators': [<wtforms.validators.Required object at 0x7f62f59b5590>, <wtforms.validators.Length object at 0x7f62f59b55d0>]})>
, not an actual field. how do i get an actual form/field with the wtform?
回答1:
You're passing a form class not a form instance to the template. The model_form
method generates a new class dynamically, which can be re-used, extended, and otherwise used like any other form subclass. It's also quite un-necessary to generate this form class on every run of your view, so you can move this call outside of your view.
You passing an uninstantiated class is also why you get strange behavior relating to UnboundField (which is how WTForms handles declarative field instantiation)
The fix is simple:
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)
回答2:
You need to do a bit more work:
{{ form.name.label }} : {{ form.name()|safe }}
Or, you can use this 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 %}
Of course, adjust the HTML rendered. Save that file somewhere in your templates
directory and then in your main template. Here its 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>
回答3:
I know this is pretty old, but I had the same problem and I want to share my solution for futures needs.
I also got the html rendered by "UnboundField". After fighting with the code I found out i'm using:
from wtforms import Form
And it's looks good, but when using Flask I had to do this:
from flask.ext.wtf import Form
Fixed my problem. Hope it's helped
来源:https://stackoverflow.com/questions/16406496/rendering-forms-with-flask-wtform