【问题标题】:What is the technique of presenting again form which contains error?再次呈现包含错误的表单的技术是什么?
【发布时间】:2013-10-03 06:43:01
【问题描述】:

使用 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 添加了有关如何显示错误inline 的答案(我认为这是最好的方法,因为页面不会跳动),因此我将代码粘贴到我的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 %}

截图:

【问题讨论】:

    标签: python flask


    【解决方案1】:

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

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

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

    example source file。这非常漂亮,因为你可以说

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

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

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

    【讨论】:

    • 感谢宏!我想我会使用它。该表单对象在进入validate_error 方法时确实发生了变化。我使用dump() 检查它,我发现它的属性和属性不同。我接受您的回答作为已接受的答案,因为它为我们提供了一种更好的方式来显示错误,这是我最初尝试提出这个问题的尝试
    • 我仍然不确定为什么重定向时对象会发生变化,如果我在 werkzeug 代码中找到任何内容,我将更新我的答案。
    • 嗯,我是java背景的。想到继承,你不觉得是因为当我重定向的时候,receiver方法在接受给定参数的父类吗?因此,它仍然可以接受该对象,但具有传递对象的精简版本。虽然我不确定这种想法是否正确,但就像我们在这里谈论 python 的方式一样..
    【解决方案2】:

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

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

    我可以轻松渲染模板:

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

    就这么简单;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-13
      • 2015-06-15
      • 2023-04-03
      • 2019-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多