首页 > 解决方案 > 在烧瓶和 python 中出现错误“jinja2.exceptions.UndefinedError: 'form' is undefined”

问题描述

我正在尝试添加一个联系表单,女巫会将用户输入的数据存储在 csv 文件中。网站如何无法进入联系人所在的页面,并且 pycharm 显示此错误: jinja2.exceptions.UndefinedError: 'form' is undefined 以下是 app.py 中有关该表单的代码:

    class ContactForm(FlaskForm):
       name = StringField('Your Name: ', validators=[InputRequired(),length(2,10), 
              Regexp('^[A-Z][A-Za-z0-9.]*$', 0,
              'Your name must start with a letter and can only include letters, numbers, dots')])
       email = EmailField('Email', validators=[InputRequired(), Email()])
       message = TextAreaField('Message', validators=[InputRequired()], render_kw={'rows': 10})
       select = SelectField('In which category your order falls into ?', validators= 
                    [InputRequired()],
               choices=[('o1', 'Applique'), ('o2', 'Embroidery'), ('o3', 'PatchWork'), 
                          ('o4','Mixed'),('o5', 'Others')])
       submit = SubmitField('Submit')


    @app.route('/contact_form', methods=['Get','Post'])
    def handle_contact_form():
         form = ContactForm()
         if form.validate_on_submit():
              with open('data/contactInfo.csv', 'a') as f:
              writer = csv.writer(f)
              writer.writerow([form.name.data, form.email.data,form.message.data, form.select.data])
              flash('***sent successfully***')
              return redirect('/home')
         else:
             flash('oops!!!! Cant send message....')
             return render_template('/special', form=form)

这是html文件上的代码:

{% extends "BaseTemplate.html" %}
{% block head %}
{{ super() }}
{% block title %}SpecialOrder{% endblock %}
{% endblock %}

{% block header %}
{{ super() }}
{% endblock %}

{% block navbar %}
{{ super() }}
{% endblock %}

{% block contents %}
<div class="container">
{% for message in get_flashed_messages() %}{{ message }}<br/>
{% endfor %}
<form action="/contact_form" method="post" style=" padding: 60px">
    {{ form.csrf_token }}{{ form.name.label }} {{ form.name }}<br/>
    {{ form.email.label }} {{ form.email }}<br/>
    {{ form.message.label }} {{ form.message }}<br/>
    {{ form.select.label }} {{ form.select }}<br/>
    {{ form.submit }}
</form>
</div>

{% endblock %}

这是我收到的错误:

   127.0.0.1 - - [14/Apr/2020 15:08:24] "GET / HTTP/1.1" 200 -
   [2020-04-14 15:08:26,089] ERROR in app: Exception on /special [GET]
   Traceback (most recent call last):
   File "C:\Users\Nahid\PycharmProjects\Assignmet3\venv\lib\site- 
      packages\flask\app.py", line 2447, in wsgi_app
   response = self.full_dispatch_request()
   File "C:\Users\Nahid\PycharmProjects\Assignmet3\venv\lib\site- 
         packages\flask\app.py", line 1952, in full_dispatch_request
     rv = self.handle_user_exception(e)
   File "C:\Users\Nahid\PycharmProjects\Assignmet3\venv\lib\site- 
           packages\flask\app.py", line 1821, in handle_user_exception
     reraise(exc_type, exc_value, tb)
   File "C:\Users\Nahid\PycharmProjects\Assignmet3\venv\lib\site- 
         packages\flask\_compat.py", line 39, in reraise raise value
   File "C:\Users\Nahid\PycharmProjects\Assignmet3\venv\lib\site 
      packages\flask\app.py", line 1950, in full_dispatch_request
     rv = self.dispatch_request()
   File "C:\Users\Nahid\PycharmProjects\Assignmet3\venv\lib\site- 
      packages\flask\app.py", line 1936, in dispatch_request
     return self.view_functions[rule.endpoint](**req.view_args)
   File "C:\Users\Nahid\PycharmProjects\Assignmet3\venv\lib\site - 
     packages\flask_login\utils.py", line 272, in decorated_view
      return func(*args, **kwargs)
   File "C:\Users\Nahid\PycharmProjects\Assignmet3\app.py", line 134, in 
         special
     return render_template("SpecialOrder.html")
   File "C:\Users\Nahid\PycharmProjects\Assignmet3\venv\lib\site- 
         packages\flask\templating.py", line 140, in render_template ctx.app,
   File "C:\Users\Nahid\PycharmProjects\Assignmet3\venv\lib\site- 
      packages\flask\templating.py", line 120, in _render
     rv = template.render(context)
   File "C:\Users\Nahid\PycharmProjects\Assignmet3\venv\lib\site- 
      packages\jinja2\environment.py", line 1090, in render
      self.environment.handle_exception()
   File "C:\Users\Nahid\PycharmProjects\Assignmet3\venv\lib\site- 
       packages\jinja2\environment.py", line 832, in handle_exception
        reraise(*rewrite_traceback_stack(source=source))
   File "C:\Users\Nahid\PycharmProjects\Assignmet3\venv\lib\site- 
      packages\jinja2\_compat.py", line 28, in reraise
      raise value.with_traceback(tb)
   File "C:\Users\Nahid\PycharmProjects\Assignmet3\templates\SpecialOrder.html", line 1, in top-level template code
     {% extends "BaseTemplate.html" %}
   File"C:\Users\Nahid\PycharmProjects\Assignmet3\ 
          templates\BaseTemplate.html", line 154, in top-level template code
     {% block contents %}
   File "C:\Users\Nahid\PycharmProjects\Assignmet3\ 
            templates\SpecialOrder.html", line 37, in block "contents"
     {{ form.csrf_token }}
   File "C:\Users\Nahid\PycharmProjects\Assignmet3\venv\lib\ site- 
          packages\jinja2\environment.py", line 471, in getattr
      return getattr(obj, attribute)
   jinja2.exceptions.UndefinedError: 'form' is undefined
   127.0.0.1 - - [14/Apr/2020 15:08:26] "GET /special HTTP/1.1" 500 -

标签: pythonflask

解决方案


您可能需要稍微调整您的路线逻辑。您看到的错误消息意味着您正在尝试加载 HTML 文件而不传入form对象。您可能会遇到某种类型的循环引用问题,即您重定向到另一条路线,然后错误地重定向这条路线,但是如果没有看到您的其余代码,就不可能知道。

我可以告诉你的是,你可能希望你的路线看起来更像这样(为简洁而编辑)

@app.route('/contact_form', methods=['GET','POST'])
def handle_contact_form():
    form = ContactForm()
    if form.validate_on_submit():
        # check some stuff
        if True:  # your stuff worked
            flash('Success')
            return redirect(url_for('home'))
        flash('Error')
        return redirect(url_for('home'))
    return render_template('specialOrder.html', form=form)

当你打电话时form.validate_on_submit(),这和说是一样的if request.method=='POST' and form.validate(),这意味着如果要么

  • 该请求不是 POST 请求,或者
  • 表格无效,

那么内部逻辑将不会被执行。我认为正在发生的是,当这种情况失败时,您的路线没有安全的“回退”,而是由于一些奇怪的行为(可能是 Jinja2 模板加载器,它不惜一切代价试图找到要返回的东西)它仍在尝试对文件进行模板化,就好像您刚刚render_template('specialOrder.html')在没有表单的情况下调用一样。只是想着所有的可能性。


推荐阅读