【问题标题】:I'm having problems with wtforms selectfields when i use a POST with Flask当我将 POST 与 Flask 一起使用时,我遇到了 wtforms 选择字段的问题
【发布时间】:2013-04-02 22:31:44
【问题描述】:

我对 wtforms 和烧瓶还很陌生,并且在使用 selectfields 时遇到了错误。表单本身在没有选择字段的情况下工作得很好,但有了它我得到以下错误:

错误:

....fields.py", line 386, in pre_validate
    for v, _ in self.choices: TypeError: 'NoneType' object is not iterable

我看到了选择域,所以它正在被渲染。我怀疑在 POST 上没有正确验证 id 并且没有返回任何内容。或者它与我返回的选择字段元组有关?此外,我使用的 ID 字段是从 GAE 的 ndb 自动 key().id() 中提取的,它相当长且令人讨厌。可能是用于选择字段的 id 长度太长?

谷歌搜索并没有提供太多关于确切问题的信息,所以我想我会在这里发布。相关代码如下。如果我遗漏了什么,请告诉我

views.py 代码:

@app.route('/new/post', methods = ['GET', 'POST'])
@login_required
def new_post():

    form = PostForm()
    if form.validate_on_submit():
        post = Post(title = form.title.data,
                    content = form.content.data,
                    hometest = form.hometest.data,
                    author = users.get_current_user())
        post.put()
        flash('Post saved on database.')
        return redirect(url_for('list_posts'))
    form.hometest.choices = [ (h.key.id(),h.homename)for h in Home.query()]

    return render_template('new_post.html', form=form)

myforms.py

class PostForm(Form):
    title = wtf.TextField('Title', validators=[validators.Required()])
    content = wtf.TextAreaField('Content', validators=[validators.Required()])
    hometest = wtf.SelectField(u'Home Name List', coerce=int,validators=[validators.optional()])

new_post.html:

{% extends "base.html" %}

{% block content %}
    <h1 id="">Write a post</h1>
    <form action="{{ url_for('new_post') }}" method="post" accept-charset="utf-8">
        {{ form.csrf_token }}
        <p>
            <label for="title">{{ form.title.label }}</label><br />
            {{ form.title|safe }}<br />
            {% if form.title.errors %}
            <ul class="errors">
                {% for error in form.title.errors %}
                <li>{{ error }}</li>
                {% endfor %}
            </ul>
            {% endif %}
        </p>
        <p>
            <label for="title">{{form.hometest.label}}</label><br/>
            {{form.hometest}}
            {% if form.hometest.errors %}
        <ul class="errors">
            {% for error in form.hometest.errors %}
            <li>{{ error }}</li>
            {% endfor %}
        </ul>
        {% endif %}
        </p>
        <p>
            <label for="title">{{ form.content.label }}</label><br />
            {{ form.content|safe }}<br />

            {% if form.content.errors %}
            <ul class="errors">
                {% for error in form.content.errors %}
                <li>{{ error }}</li>
                {% endfor %}
            </ul>
            {% endif %}
        </p>
        <p><input type="submit" value="Save post"/></p>
    </form>
{% endblock %}

【问题讨论】:

    标签: python flask wtforms flask-wtforms


    【解决方案1】:

    您需要在调用validate_on_submit 之前设置您的选择,因为form.validate 将尝试根据选择列表(即None 在您之前验证提供的值(如果有)设置choices):

    form = PostForm()
    form.hometest.choices = [(h.key.id(), h.homename) for h in Home.query()]
    
    if form.validate_on_submit():
        # form is valid, continue
    

    【讨论】:

    • 如果您不想对其进行验证,如何使其跳过特定字段?我收到验证器=[validators.optional()] 的日期字段错误
    • 值得用一个最小的、可重复的例子提出一个单独的问题。有人应该能够提供帮助:-)
    • 这正是我通过这个答案解决的问题。
    • 非常感谢!我正在努力解决同样的问题。移动 myform.choices= 不管 form.validate_on_submit () 修复它!
    • 哦,谢谢!我正在处理这个错误一个小时,这正是我的问题的解决方案!
    【解决方案2】:

    您应该提供choices=[...] 参数,例如

    wtf.SelectField(u'Home Name List',
                    choices=[(1, 'Label 1'),
                             (2, 'Label 2')],
                    coerce=int,
                    validators=[validators.optional()])
    

    【讨论】:

    • 看来您实际上不能使用 selectField 中的选择参数进行动态选择,如文档 wtforms.readthedocs.io/en/latest/... 中所示,因为即使您的选择参数在选择字段是wtf.SelectField(u'Home Name List', choices=[(h.key.id(), h.homename) for h in Home.query()], coerce=int) 中的查询,该查询不会在每次显示表单时运行.. 因此动态添加的 home 实例不会出现在下拉列表中.. 根据我的测试
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多