我如何解决这个Flask-WTF问题:Jinja2.exceptions.UndefinedError:'wtforms.fields.core.UnboundField对象'没有属性'label'

问题描述 投票:0回答:1

我相对较不熟悉编码,因此对于任何含糊或错误之处深表歉意。请纠正我。我一直在关注Corey Schafers Flask教程,在第3部分中,我一直卡在以下错误中:Jinja2.exceptions.UndefinedError:'wtforms.fields.core.UnboundField object'没有属性'label',而试图运行以下注册页面:

register.html

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

                    {% if form.username.errors %}
                        {{ form.username(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.username.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.username(class="form-control form-control-lg") }}
                    {% endif %}
                </div>
                <div class="form-group">
                    {{ form.email.label(class="form-control-label") }}
                    {% if form.email.errors %}
                        {{ form.email(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.email.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.email(class="form-control form-control-lg") }}
                    {% endif %}
                </div>
                <div class="form-group">
                    {{ form.password.label(class="form-control-label") }}
                    {% if form.password.errors %}
                        {{ form.password(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.password.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.password(class="form-control form-control-lg") }}
                    {% endif %}
                </div>
                <div class="form-group">
                    {{ form.confirm_password.label(class="form-control-label") }}
                    {% if form.confirm_password.errors %}
                        {{ form.confirm_password(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.confirm_password.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.confirm_password(class="form-control form-control-lg") }}
                    {% endif %}
                </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 %}

其他相关文件:

Forms.py

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, BooleanField
from wtforms.validators import DataRequired, Length, Email, EqualTo

class RegistrationForm(FlaskForm):
    username = StringField('Username',
                           validators=[DataRequired(), Length(min=2, max=20)])
    email = StringField('Email',
                        validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    confirm_password = PasswordField('Confirm Password',
                                     validators=[DataRequired(), EqualTo('password')])
    submit = SubmitField('Sign Up')


class LoginForm(FlaskForm):
    email = StringField('Email',
                        validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    remember = BooleanField('Remember Me')
    submit = SubmitField('Login')

flaskblog.py

from flask import Flask, render_template, url_for
from forms import RegistrationForm, LoginForm
...
@app.route('/register')
def register():
    form = RegistrationForm
    return render_template('register.html', title='register', form=form)

这是来自服务器的回溯:

Traceback (most recent call last):
  File "C:\Users\Musa\Desktop\Flask_Blog\lib\site-packages\flask\app.py", line 2464, in __call__
    return self.wsgi_app(environ, start_response)
  File "C:\Users\Musa\Desktop\Flask_Blog\lib\site-packages\flask\app.py", line 2450, in wsgi_app
    response = self.handle_exception(e)
  File "C:\Users\Musa\Desktop\Flask_Blog\lib\site-packages\flask\app.py", line 1867, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\Musa\Desktop\Flask_Blog\lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "C:\Users\Musa\Desktop\Flask_Blog\lib\site-packages\flask\app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\Musa\Desktop\Flask_Blog\lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\Musa\Desktop\Flask_Blog\lib\site-packages\flask\app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\Musa\Desktop\Flask_Blog\lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "C:\Users\Musa\Desktop\Flask_Blog\lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\Musa\Desktop\Flask_Blog\lib\site-packages\flask\app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Users\Musa\Desktop\Flask_Blog\flask_blog.py", line 39, in register
    return render_template('register.html', title='register', form=form)
  File "C:\Users\Musa\Desktop\Flask_Blog\lib\site-packages\flask\templating.py", line 140, in render_template
    ctx.app,
  File "C:\Users\Musa\Desktop\Flask_Blog\lib\site-packages\flask\templating.py", line 120, in _render
    rv = template.render(context)
  File "C:\Users\Musa\Desktop\Flask_Blog\lib\site-packages\jinja2\environment.py", line 1090, in render
    self.environment.handle_exception()
  File "C:\Users\Musa\Desktop\Flask_Blog\lib\site-packages\jinja2\environment.py", line 832, in handle_exception
    reraise(*rewrite_traceback_stack(source=source))
  File "C:\Users\Musa\Desktop\Flask_Blog\lib\site-packages\jinja2\_compat.py", line 28, in reraise
    raise value.with_traceback(tb)
  File "C:\Users\Musa\Desktop\Flask_Blog\templates\register.html", line 1, in top-level template code
    {% extends "layout.html" %}
  File "C:\Users\Musa\Desktop\Flask_Blog\templates\layout.html", line 47, in top-level template code
    {% block content %}{% endblock %}
  File "C:\Users\Musa\Desktop\Flask_Blog\templates\register.html", line 9, in block "content"
    {{ form.username.label(class="form-control-label") }}
jinja2.exceptions.UndefinedError: 'wtforms.fields.core.UnboundField object' has no attribute 'label'

我如何解决这个问题?我尝试查看WTForms文档,它说:

“ _如果未提供_form和_name,则将返回UnboundField。使用表单实例和名称来调用其bind()方法以构造字段。”

https://wtforms.readthedocs.io/en/stable/fields/#wtforms.fields.Label

因此,我知道label属性没有接收到表单或名称,但是表单控件在做什么?我不知道该如何理解。我尝试对Corey Schafer的git文件夹上的代码进行校对,但仍然无济于事:https://github.com/CoreyMSchafer/code_snippets/tree/master/Python/Flask_Blog/03-Forms-and-Validation请帮忙!

python html flask jinja2 flask-wtforms
1个回答
0
投票

在flaskblog.py中,将class RegistrationForm分配为变量形式。不是instance。这种添加的括号应该可以解决。

@app.route('/register')
def register():
    form = RegistrationForm() # Added parenthesis here. 
    return render_template('register.html', title='register', form=form)
© www.soinside.com 2019 - 2024. All rights reserved.