jinja2.exceptions.UndefinedError: 'str object&

2019-08-11 10:15发布

问题:

I am having issues getting my flask app to recognize my form variables when trying to load the register.html page. I have tried to reload my virtualenv and have tried to load the template code from another person and I get the same error. Here is the traceback I am getting.

File "s:\projects\gameapp\env\lib\site-packages\flask\app.py", line 2309, in __call__
return self.wsgi_app(environ, start_response)
File "s:\projects\gameapp\env\lib\site-packages\flask\app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
File "s:\projects\gameapp\env\lib\site-packages\flask\app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
File "s:\projects\gameapp\env\lib\site-packages\flask\_compat.py", line 35, in reraise
raise value
File "s:\projects\gameapp\env\lib\site-packages\flask\app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "s:\projects\gameapp\env\lib\site-packages\flask\app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "s:\projects\gameapp\env\lib\site-packages\flask\app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "s:\projects\gameapp\env\lib\site-packages\flask\_compat.py", line 35, in reraise
raise value
File "s:\projects\gameapp\env\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "s:\projects\gameapp\env\lib\site-packages\flask\app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "S:\Projects\gameapp\gameapp.py", line 35, in register
return render_template('register.html', title='Register', form='form')
File "s:\projects\gameapp\env\lib\site-packages\flask\templating.py", line 135, in render_template
context, ctx.app)
File "s:\projects\gameapp\env\lib\site-packages\flask\templating.py", line 117, in _render
rv = template.render(context)
File "s:\projects\gameapp\env\lib\site-packages\jinja2\asyncsupport.py", line 76, in render
return original_render(self, *args, **kwargs)
File "s:\projects\gameapp\env\lib\site-packages\jinja2\environment.py", line 1008, in render
return self.environment.handle_exception(exc_info, True)
File "s:\projects\gameapp\env\lib\site-packages\jinja2\environment.py", line 780, in handle_exception
reraise(exc_type, exc_value, tb)
File "s:\projects\gameapp\env\lib\site-packages\jinja2\_compat.py", line 37, in reraise
raise value.with_traceback(tb)
File "S:\Projects\gameapp\templates\register.html", line 1, in top-level template code
{% extends "layout.html" %}
File "S:\Projects\gameapp\templates\layout.html", line 44, in top-level template code
{% block content %}{% endblock %}
File "S:\Projects\gameapp\templates\register.html", line 9, in block "content"
{{ username.label(class="form-control-label") }}
File "s:\projects\gameapp\env\lib\site-packages\jinja2\environment.py", line 430, in getattr
return getattr(obj, attribute)

Here is my registration.html page

{% extends "layout.html" %}
{% block content %}
    <div class="content-section">
        <form method="POST" action="">
            {{ form.hidden_tag }}
            <fieldset class="form-group">
                <legend class="border-bottom mb-4">Join Today</legend>
                <div class="form-group">
                    {{ form.username.label(class="form-control-label") }}
                    {{ form.username(class="form-control form-control-lg") }}
                </div>
                <div class="form-group">
                    {{ form.email.label(class="form-control-label")}}
                    {{ form.email(class="form-control form-control-lg")}}
                </div>
                <div class="form-group">
                    {{ form.password.label(class="form-control-label") }}
                    {{ form.password(class="form-control form-control-lg") }}
                </div>
                <div class="form-group">
                    {{ form.confirm_password.label(class="form-control-label") }}
                    {{ form.confirm_password(class="form-control form-control-lg") }}
                </div>
            </fieldset>
            <div class="form-group">
                {{ form.submit(class="btn btn-outline-info") }}
            </div>
        </form>
    </div>
    <div class="border-top pt-3">
        <small class="text-muted">
            Already Have An Account? <a class="ml-2" href="{{ url_for('login') }}">Sign In</a>
        </small>
    </div>
{% endblock content %}

I've tried to remove the code it is throwing the error on and I just get an error on the next line saying no attribute 'email', I'm thinking it has to do with a version error as everything works fine except this (currently). Any help would be appreciated.

回答1:

You need to use "class_" attribute to label, not the "class", which means you need to fix

{{ form.username.label(class="form-control-label") }}

to

{{ form.username.label(class_="form-control-label") }}

and so on throughout the template.



回答2:

As user @Andellys mentions, you should change from class to class_ but also, maybe you haven't instantiated your form. Please check this answer: hidden_tag() missing 1 required positional argument: 'self' in flask forms?.



回答3:

Before solving your error you need to first understand it.

Here, the error clearly states that str object has no attribute username. It means that the object that uses the attribute called username is of type str (whereas it should be an object of a form class).

It would have been easy had you posted the python code of the form also, but still I'll let's try to figure out the problem.

Let's say the name of your form class is Form, i.e. its declaration goes like:

class Form(FlaskForm):

then in your python file that renders registration.html you'd have to do something like

form = Form()

My best guess is, you've put your class name in quotes

forms = 'Forms()'

and because of that python interprets it as str object rather than Form object

So just remove the quotations from the instantiation statement and you are good to go.

Hope that helps :)