简体   繁体   中英

having the error “ jinja2.exceptions.UndefinedError: 'form' is undefined ” in flask and python

i'm trying to add a contact form witch will store the data entered by the user in a csv file. How ever the site won't proceed to the page in which the contact for is and the pycharm is showing this error: jinja2.exceptions.UndefinedError: 'form' is undefined Here is the code regarding that form in 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)

and this is the code on the html file:

{% 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 %}

this the errors i recieve:

   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 -

This seemes no the right way. I think the easy way is to put in the else part the represantation of the form. And keep the if. About the error, you can make an if inside the else. Or make an if inside the jinja -html,meaning after entering data..something went wrong. This is the best way in my opinion.

You might want to adjust your route logic slightly. The error message you are seeing means that you are trying to load the HTML file without passing in the form object. There is a chance you are experiencing some type of circular reference issue where you redirect to another route and then redirect back to this one incorrectly, but without seeing the rest of your code it is impossible to know.

What I can tell you is that you will probably want your route to look more like this (edited for brevity)

@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)

When you call form.validate_on_submit() that is the same thing as saying if request.method=='POST' and form.validate() , which means that if either

  • the request is not a POST request, or
  • the form is not valid,

then the inner logic will not be executed. What I think is happening is that your route does not have a safe "fallback" for when this condition is failing, but because of some odd behavior (maybe with the Jinja2 template loader, which tries at all costs to find something to return) it is still trying to template the file as if you had just called render_template('specialOrder.html') with no form. Just thinking of all possibilities.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM