2014-04-06 34 views
4

當我嘗試驗證用戶提供的數據並檢查輸入的電子郵件是否存在時,我的小型註冊應用程序出現錯誤。Flask self.errors.append() - AttributeError:'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' 

回答

10

tuple對象cannot append。相反,轉換爲使用list()列表,並且追加,再轉換回,因爲這樣的:

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

希望這有助於!

+0

非常感謝。 我嘗試了一些不同,但使用你的方法 :) – Max

+0

很高興成爲幫助:) –

+1

[wtforms文檔狀態](http://wtforms.simplecodes.com/docs/1.0.3/fields.html#wtforms .fields.Field.errors)'errors'是一個列表:'errors:如果驗證遇到任何錯誤,它們將被插入到這個列表中。「這無論如何是我混亂的根源。 – Jon

3

tuples是不可變的類型,這意味着您不能拼接併爲其分配值。如果你要與你需要添加值和刪除值,使用列表,而不是數據類型來工作:

>>> 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] 
+0

謝謝。爲了您的評論:) – Max

3

剛剛遇到這個我自己。我認爲對你的問題更好的回答是你應該在向他們添加錯誤之前驗證元素。驗證過程將錯誤字段設置爲一個列表,如果您在驗證字段之前更改它,它將在您驗證時寫入。

因此,重寫窗體的validate方法,調用父驗證方法,然後在其中運行您的email_unique方法。

然後你可以從視圖中刪除email_unique,因爲這將是你的validate_on_submit

1

答案是深一點的一部分。當創建Field類時,「errors」是一個元組。

class Field(object): 
    """ 
    Field base class 
    """ 
    errors = tuple() 

但是,當調用的方法驗證,將其轉換它列出

def validate(self, form, extra_validators=tuple()): 
    self.errors = list(self.process_errors) 

所以,你需要的一切只是打電話給你email_unique功能validate_on_submit之後,這反過來調用驗證表單的功能,將錯誤轉換爲列表

@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) 
相關問題