3

使用 Flask + Flask-Classy + WTForms,我正在尝试实现一个路由,这样,当用户在输入表单中出现错误时,应用程序将再次向用户呈现该表单,并完成用户已经填写的内容。这样,用户不必担心再次输入所有表单输入:(s)他可以纠正错误。

这些是来自我的类​​ UserView(FlaskView) 的代码,它是一个烧瓶类:

def post(self):                                                                                                                                                                                                               
    form = forms.UserForm(request.form)                                                                                                                                                                                       
    if form.validate():                                                                                                                                                                                                       
        if form.id.data=='':                                                                                                                                                                                                  
            user = models.Users()                                                                                                                                                                                             
            form.populate_obj(user)                                                                                                                                                                                           
            user.id = None                                                                                                                                                                                                    
            db.session.add(user)                                                                                                                                                                                              
        else:                                                                                                                                                                                                                 
            user = models.Users.query.get(form.id.data)                                                                                                                                                                       
            form.populate_obj(user)                                                                                                                                                                                           

        db.session.commit()                                                                                                                                                                                                   
        return redirect(url_for('UserView:index'))                                                                                                                                                                            
    else:                                                                                                                                                                                                                     
       return redirect(url_for('UserView:validation_error', error_form=form))                                                                                                                                                 

def validation_error(self, error_form):                                                                                                                                                                                       
    return render_template('users/form.html', form=error_form)       

您可以看到,在这次尝试中,我尝试创建另一个方法 : validation_error,带有参数——在我的期望中——应该包含所有表单数据。但是,事实证明我得到了 Jinja2 异常,UndefinedError: 'unicode object' has no attribute 'hidden_tag'. 当我检查它时,在进入之后validation_error,该form对象在某种程度上从UserForm变成了某种unicode对象。

有什么建议吗?或者,是我试图以错误的方向解决这个问题吗?

编辑 1:详细说明如何显示错误

由于@Rawrgulmuffins 添加了一个关于如何内联显示错误的答案(我认为这是最好的方法,因为页面不会变得跳跃),所以我将代码粘贴到我layout.html的所有错误列表中。它可能不如内联错误显示好,但我认为这是最简单的方法。首先我为表单对象做一个 if,因为这个代码也存在于所有页面(我可能会重构它更多)

 {% if form %}
                {% for error in form.errors %}
                <div class="alert alert-error">
                    <a class="close" data-dismiss="alert">×</a>
                    <strong>{{ form[error].label }} {{form.errors[error][0] }}</strong>
                </div>
 {% endfor %}
 {% endif %}

给出的截图:

验证错误显示

4

2 回答 2

2

我正在添加我的答案,以扩展 swdev 对任何不明白为什么他只能渲染模板并显示错误的人的答案。

表单中的每个字段都包含一个错误属性,该属性将在验证后(之后form.validate())填充。这些错误将包含在表单对象中。所以你可以这样说,

{% if field.errors %}
    <span class="error help-inline">{{ field.errors|join(', ') }}</span>
{% endif %}

示例源文件。这非常好,因为你可以说

 return render_template('users/form.html', form=form) 

如果它是第一次渲染,则获得无错误表单并仅在表单的第二次渲染时显示错误。

我不确定为什么 Swdev 尝试重定向表单导致它现在被操纵。我现在正在查看 Werkzeug 代码,看看是否能找到答案。

于 2013-10-03T17:46:01.083 回答
1

哦,我是多么愚蠢。就在我休息了一会儿之后,我找到了一个简单的答案,那就是,而不是传递给另一个视图方法:

else:                                                                                                                                                                                                                     
   return redirect(url_for('UserView:validation_error', error_form=form))

我可以轻松地渲染模板:

  return render_template('users/form.html', form=form) 

就这么简单;)

于 2013-10-03T08:54:43.347 回答