Flask self.errors.append() - 属性错误:'tuple'对象没有'append'属性
我这个小注册应用在尝试验证用户提交的数据时出错,特别是检查输入的电子邮件是否存在时。
这是我的文件:
表单:
from flask.ext.wtf import Form
from wtforms import TextField, BooleanField, PasswordField, TextAreaField, validators
from wtforms.validators import Required
from app import models
class RegisterForm(Form):
"""RegisterForm class needed for retrieving data from user"""
username = TextField('username', [validators.Length(min=3, max=50), validators.Required()])
email = TextField('email', [validators.Length(min=3, max=100), validators.Required()])
password = PasswordField('password', [validators.Required()])
age = TextField('age', [validators.Length(min=1, max=3), validators.Required()])
about_user = TextAreaField('about_user', [validators.Length(max=500)])
img_url = TextField('img_url')
def email_unique(self, email):
if models.User.query.filter_by(email = email).first() != None:
self.email.errors.append('This E-mail address is already in use. Please choose another one.')
return False
视图:
#!flask/bin/python
from app import app, db, lm
from flask import render_template, url_for, flash, g, redirect, session, request
from flask.ext.login import login_user, logout_user, current_user, login_required
from forms import LoginForm, RegisterForm, EditForm
from models import User
@app.route('/register', methods = ['GET', 'POST'])
def register():
form = RegisterForm()
#makes the username unique
u_unique = form.username.data
u_unique = User.unique_username(u_unique)
#validates email adress and checks if it already exists or not
form.email_unique(form.email.data)
if form.validate_on_submit():
user = User(
u_unique,
form.password.data,
form.email.data,
form.age.data,
form.about_user.data,
form.img_url.data)
db.session.add(user)
db.session.commit()
flash('Thank you for your registration')
flash('Your username is: ' + str(u_unique))
return redirect(url_for('login'))
else:
for error in form.errors:
flash(error)
return render_template('register.html',
title = 'Registeration',
form = form)
错误信息是:
Traceback (most recent call last) File <br> "/home/maksad/Desktop/faskMonkey/flask/lib/python2.7/site-packages/flask/app.py", line 1701, in __call__ return self.wsgi_app(environ, start_response)
File "/home/maksad/Desktop/faskMonkey/flask/lib/python2.7/site-packages/flask/app.py", line 1689, in wsgi_app response = self.make_response(self.handle_exception(e))
File "/home/maksad/Desktop/faskMonkey/flask/lib/python2.7/site-packages/flask/app.py", line 1687, in wsgi_app response = self.full_dispatch_request()
File "/home/maksad/Desktop/faskMonkey/flask/lib/python2.7/site-packages/flask/app.py", line 1360, in full_dispatch_request rv = self.handle_user_exception(e)
File "/home/maksad/Desktop/faskMonkey/flask/lib/python2.7/site-packages/flask/app.py", line 1358, in full_dispatch_request rv = self.dispatch_request()
File "/home/maksad/Desktop/faskMonkey/flask/lib/python2.7/site-packages/flask/app.py", line 1344, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args)
File "/home/maksad/Desktop/faskMonkey/app/views.py", line 92, in register form.email_unique(form.email.data)
File "/home/maksad/Desktop/faskMonkey/app/forms.py", line 26, in email_unique
self.email.errors.append('This E-mail address is already in use. Please choose another one.')
AttributeError: 'tuple' object has no attribute 'append'
4 个回答
3
这个答案有点复杂。“errors”在创建Field类的时候是一个元组。
class Field(object):
"""
Field base class
"""
errors = tuple()
但是当调用validate方法时,它会把这个元组转换成一个列表。
def validate(self, form, extra_validators=tuple()):
self.errors = list(self.process_errors)
所以你需要做的就是在调用validate_on_submit
之后,紧接着调用你的email_unique
函数,这样validate_on_submit
就会调用表单的validate函数,并把错误转换成列表。
@app.route('/register', methods = ['GET', 'POST'])
def register():
form = RegisterForm()
#makes the username unique
u_unique = form.username.data
u_unique = User.unique_username(u_unique)
#validates email adress and checks if it already exists or
if form.validate_on_submit():
form.email_unique(form.email.data)
user = User(
u_unique,
form.password.data,
form.email.data,
form.age.data,
form.about_user.data,
form.img_url.data)
db.session.add(user)
db.session.commit()
flash('Thank you for your registration')
flash('Your username is: ' + str(u_unique))
return redirect(url_for('login'))
else:
for error in form.errors:
flash(error)
return render_template('register.html',
title = 'Registeration',
form = form)
3
tuples
是一种不可变的数据类型,这意味着你不能对它们进行切片或赋值。如果你需要处理的数据类型需要添加或删除值,建议使用列表(list)来代替:
>>> a = (1,2,3)
>>> a.append(2)
AttributeError: 'tuple' object has no attribute 'append'
>>> b = [1,2,3]
>>> b.append(2)
[1,2,3,2]
5
我刚好遇到这个问题。我觉得更好的回答是,在你给元素添加错误之前,应该先验证这些元素。验证的过程会把错误信息放到一个列表里,如果你在验证字段之前就修改了这个列表,等你验证的时候它会被覆盖掉。
所以,你需要重写你表单的验证方法,先调用父类的验证方法,然后再运行你的 email_unique 方法。
这样你就可以把视图中的 email_unique 移除了,因为它会成为你提交时验证的一部分。
14
这个 tuple
对象是不能直接添加元素的。你可以先把它转换成一个列表,用 list()
这个方法,然后在列表里添加元素,最后再把它转换回 tuple
。具体操作可以参考下面的代码:
>>> obj1 = (6, 1, 2, 6, 3)
>>> obj2 = list(obj1) #Convert to list
>>> obj2.append(8)
>>> print obj2
[6, 1, 2, 6, 3, 8]
>>> obj1 = tuple(obj2) #Convert back to tuple
>>> print obj1
(6, 1, 2, 6, 3, 8)
希望这对你有帮助!