rendering forms with flask + wtform

↘锁芯ラ 提交于 2019-12-04 03:20:42

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!