1
votes

The problem relates to the use of the SelectField option where I want to offer all clubs from the database to the use and accept back the chosen club when they complete the form.

The list of clubs is correctly provided on the form but when one is selected and the submit button is hit I get this message:

"TypeError: 'NoneType' object is not iterable" message.

My Routes code :

@bp.route('/register', methods=['GET', 'POST'])
def register():
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))
    clubs = []
    form = RegistrationForm()
    if form.validate_on_submit():
        clubnumber = int(form.club.data) +1
        usernumber = clubnumber * 1000000
        nextuser = (db.session.query(func.max(User.usernum)).filter(User.usernum<usernumber).scalar() or 0)
        print(nextuser)
        nextuser = nextuser +1
        user = User(username=form.username.data, email=form.email.data, usernum=nextuser,club=form.club.data)
        user.set_password(form.password.data)
        db.session.add(user)
        db.session.commit()
        flash(_('Congratulations, you are now a registered user! %(nextuser)s!'))
        return redirect(url_for('auth.login'))
    elif request.method == 'GET':
        clubrows = Club.query.all()
        for club in clubrows:
            clubs.append(club.clubnum)
            clubs.append(club.clubname)
        form.club.choices = [(row.clubnum, row.clubname) for row in Club.query.all()]
    return render_template('auth/register.html', title=_('Register'),  form=form)

My form code :

class RegistrationForm(FlaskForm):
    username = StringField(_l('Username'), validators=[DataRequired()])
    email = StringField(_l('Email'), validators=[DataRequired(), Email()])
    password = PasswordField(_l('Password'), validators=[DataRequired()])
    password2 = PasswordField(
        _l('Repeat Password'), validators=[DataRequired(),
                                           EqualTo('password')])
    club =SelectField(_l('Club' ))
    submit = SubmitField(_l('Register'))

    def validate_username(self, username):
        user = User.query.filter_by(username=username.data).first()
        if user is not None:
            raise ValidationError(_('Please use a different username.'))

    def validate_email(self, email):
        user = User.query.filter_by(email=email.data).first()
        if user is not None:
            raise ValidationError(_('Please use a different email address.'))

The full error text received :

[2019-09-29 12:40:41,359] INFO in init: Microblog startup * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) 127.0.0.1 - - [29/Sep/2019 12:40:47] "GET /auth/register HTTP/1.1" 200 -

[2019-09-29 12:41:09,845] ERROR in app: Exception on /auth/register [POST]

Traceback (most recent call last): File "C:\Users\tribl\PycharmProjects\CM2020\venv\lib\site-packages\flask\app.py", line 2446, in wsgi_app response = self.full_dispatch_request()

File "C:\Users\tribl\PycharmProjects\CM2020\venv\lib\site-packages\flask\app.py", line 1951, in full_dispatch_request rv = self.handle_user_exception(e)

File "C:\Users\tribl\PycharmProjects\CM2020\venv\lib\site-packages\flask\app.py", line 1820, in handle_user_exception reraise(exc_type, exc_value, tb)

File "C:\Users\tribl\PycharmProjects\CM2020\venv\lib\site-packages\flask_compat.py", line 39, in reraise raise value

File "C:\Users\tribl\PycharmProjects\CM2020\venv\lib\site-packages\flask\app.py", line 1949, in full_dispatch_request rv = self.dispatch_request()

File "C:\Users\tribl\PycharmProjects\CM2020\venv\lib\site-packages\flask\app.py", line 1935, in dispatch_request return self.view_functionsrule.endpoint

File "C:\Users\tribl\PycharmProjects\CM2020\app\auth\routes.py", line 54, in register if form.validate_on_submit():

File "C:\Users\tribl\PycharmProjects\CM2020\venv\lib\site-packages\flask_wtf\form.py", line 101, in validate_on_submit return self.is_submitted() and self.validate()

File "C:\Users\tribl\PycharmProjects\CM2020\venv\lib\site-packages\wtforms\form.py", line 310, in validate return super(Form, self).validate(extra)

File "C:\Users\tribl\PycharmProjects\CM2020\venv\lib\site-packages\wtforms\form.py", line 152, in validate if not field.validate(self, extra): File "C:\Users\tribl\PycharmProjects\CM2020\venv\lib\site-packages\wtforms\fields\core.py", line 195, in validate self.pre_validate(form)

File "C:\Users\tribl\PycharmProjects\CM2020\venv\lib\site-packages\wtforms\fields\core.py", line 471, in pre_validate for v, _ in self.choices:

TypeError: 'NoneType' object is not iterable 127.0.0.1 - - [29/Sep/2019 12:41:09] "POST /auth/register HTTP/1.1" 500 -

1

1 Answers

0
votes

There is probably something going wrong in your validatos, since File "C:\Users\tribl\PycharmProjects\CM2020\app\auth\routes.py", line 54, in register if form.validate_on_submit(): is among your errors. Are you sure your validators are working as expected? Maybe try to set a breakpoint on those.

Another thing I have had issues with in the past is selecting an element from an empty list. So instead of :

        user = User.query.filter_by(username=username.data).first()
        if user is not None:
            raise ValidationError(_('Please use a different username.'))

you could try:

        user = User.query.filter_by(username=username.data)
        if len(user) > 0:
            user = user.first()
        else:
            raise ValidationError(_('Please use a different username.'))

and similar for validate_email.

Hope this helps!