问题
Why do I get this error? What is the UnboundField and what do I need to know in order to fix and avoid this problem in the future?
Debug output when I visit http://127.0.0.1:5000/signup:
AttributeError
AttributeError: 'UnboundField' object has no attribute '__call__'
Traceback (most recent call last)
File "C:\Users\combatmath\Envs\default\lib\site-packages\flask\app.py", line 2000, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\combatmath\Envs\default\lib\site-packages\flask\app.py", line 1991, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "C:\Users\combatmath\Envs\default\lib\site-packages\flask\app.py", line 1567, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\combatmath\Envs\default\lib\site-packages\flask\app.py", line 1988, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\combatmath\Envs\default\lib\site-packages\flask\app.py", line 1641, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\combatmath\Envs\default\lib\site-packages\flask\app.py", line 1544, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\combatmath\Envs\default\lib\site-packages\flask\app.py", line 1639, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\combatmath\Envs\default\lib\site-packages\flask\app.py", line 1625, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\combatmath\Apps\ocrbox\routes.py", line 27, in signup
return render_template("signup.html", form=form)
File "C:\Users\combatmath\Envs\default\lib\site-packages\flask\templating.py", line 134, in render_template
context, ctx.app)
File "C:\Users\combatmath\Envs\default\lib\site-packages\flask\templating.py", line 116, in _render
rv = template.render(context)
File "C:\Users\combatmath\Envs\default\lib\site-packages\jinja2\environment.py", line 989, in render
return self.environment.handle_exception(exc_info, True)
File "C:\Users\combatmath\Envs\default\lib\site-packages\jinja2\environment.py", line 754, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\combatmath\Apps\ocrbox\templates\signup.html", line 1, in top-level template code
{% extends "base.html" %}
File "C:\Users\combatmath\Apps\ocrbox\templates\base.html", line 9, in top-level template code
{% block content %}{% endblock %}
File "C:\Users\combatmath\Apps\ocrbox\templates\signup.html", line 30, in block "content"
{{ form.submit(class="btn-primary") }}
AttributeError: 'UnboundField' object has no attribute '__call__'
signup.html:
{% extends "base.html" %}
{% block title %}Join ocrbox!{% endblock %}
{% block content %}
<main class="container signup-section">
<div class="section-content">
<h2>Create an account</h2>
<form method="POST" action="/signup">
<div class="form-group">
{{ form.first_name.label }}
{{ form.first_name }}
</div>
<div class="form-group">
{{ form.last_name.label }}
{{ form.last_name }}
</div>
<div class="form-group">
{{ form.email.label }}
{{ form.email }}
</div>
<div class="form-group">
{{ form.password.label }}
{{ form.password }}
</div>
{{ form.submit(class="btn-primary") }}
</form>
</div>
</main>
{% endblock %}
routes.py:
from flask import Flask, render_template, request
from models import db
from forms import SignupForm
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://localhost/ocrbox'
db.init_app(app)
app.secret_key = "development-key"
@app.route("/")
def index():
return render_template("index.html")
@app.route("/about")
def about():
return render_template("about.html")
@app.route("/signup", methods=['GET', 'POST'])
def signup():
form = SignupForm
if request.method == 'POST':
return "Success!"
elif request.method == 'GET':
return render_template("signup.html", form=form)
if __name__ == "__main__":
app.run(debug=True)
forms.py:
from flask_wtf import Form
from wtforms import StringField, PasswordField, SubmitField
class SignupForm(Form):
first_name = StringField('First name')
last_name = StringField('Last name')
email = StringField('Email')
password = PasswordField('Password')
submit = SubmitField('Sign up')
models.py:
from flask_sqlalchemy import SQLAlchemy
from werkzeug import generate_password_hash, check_password_hash
db = SQLAlchemy()
class User(db.Model):
__tablename__ = 'users'
uid = db.Column(db.Integer, primary_key=True)
firstname = db.Column(db.String(100))
lastname = db.Column(db.String(100))
email = db.Column(db.String(120), unique=True)
pwdhash = db.Column(db.String(54))
def __init__(self, firstname, lastname, email, password):
self.firstname = firstname.title()
self.lastname = lastname.title()
self.email = email.lower()
self.set_password(password)
def set_password(self, password):
self.pwdhash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.pwdhash, password)
回答1:
In routes.py, I think your signup()
method should contain form = SignupForm(request.form)
. Otherwise, form is set to a class instead of an instance.
来源:https://stackoverflow.com/questions/38820081/flask-attributeerror-unboundfield-object-has-no-attribute-call