Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Python

Erik Malmberg
Erik Malmberg
1,465 Points

Validation form not working

I'm trying to use validation forms on my login for the flask "Build a Social Network" course, but the validation is not working - even if I leave the form blank and hit "submit", I get no error back.

Here's the code:

from flask import Flask, g, render_template, flash, redirect, url_for
from flask_login import LoginManager

import forms
import models

app = Flask(__name__)
app.secret_key = "76^Xdadsadsadasdsa_^"

login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "login"

@login_manager.user_loader
def load_user(userid):
    try:
        return models.User.get(models.User.id == userid)
    except models.DoesNotExist:
        return None


@app.before_request
def before_request():
    """Connect to database before each request"""
    g.db = models.DATABASE
    g.db.connect()


@app.after_request
def after_request(response):
    """Close the database connection after each request"""
    g.db.close()
    return response



@app.route("/register",methods=["GET","POST"])
def register():
    form = forms.RegisterForm()
    if form.validate_on_submit():
        flash("Successful registration", "success")
        models.User.create_user(
            username=form.username.data,
            email=form.email.data,
            password=form.password.data
            )
        return redirect(url_for("index"))
    return render_template("register.html",form=form)

@app.route("/")
def index():
return "Hi"



if __name__ == "__main__":
    models.initialize()
    try:
        models.User.create_user(
            username="usernamehere",
            email="email@email.com",
            password="password",
            admin=True)
    except ValueError:
        pass

    app.run(debug=True,port=5500)

forms.py:

from flask_wtf import Form
from wtforms import StringField, PasswordField
from wtforms.validators import DataRequired, Regexp, ValidationError, Email, Length, EqualTo

from models import User

def name_exists(form, field):
    if User.select().where(User.username == field.data).exists():
        raise ValidationError("User with that name already exists")


def email_exists(form, field):
    if User.select().where(User.email == field.data).exists():
        raise ValidationError("User with that email already exists")


class RegisterForm(Form):
    username = StringField(
        "Username",
        validators=[
        DataRequired(),
        Regexp(
            r'^[a-zA-Z0-9_]+$', message=("Username should be one word, letters, "
            "numbers and underscores only")
        ),
        name_exists
        ])

    email = StringField(
        "Email",
        validators=[DataRequired(),
        Email(),
        email_exists
        ])
    password = PasswordField(
    "Password",
    validators=[DataRequired(),
    Length(min=2),
    EqualTo("password2",message="Passwords must match") 
            ])
    password2 = PasswordField(
        "Confirm Password",
        validators=[DataRequired()]
        )

macros.html:

{% macro render_field(field) %}
<div class="field">
{% if field.errors %}
    {% for errors in field.errors %}
        <div class="notification error">{{ error }}</div>
    {% endfor %}
{%  endif %}
{{ field(placeholder=field.label.text) }}
</div>
{% endmacro %}

register.html:

{% from "macros.html" import render_field %}
<form method="POST" action="" class="form">
    {{ form.hidden_tag() }}
    {% for field in form %}
        {{ render_field(field) }}
    {% endfor %}
    <button type="submit" id="submit">Register</button>
</form>

models.py:

import datetime
from flask_login import UserMixin
from flask_bcrypt import generate_password_hash
from peewee import *



DATABASE = SqliteDatabase("social.db")

class User(UserMixin, Model):
    username = CharField(unique=True)
    email = CharField(unique=True)
    password = CharField(max_length=100)
    joined_at = DateTimeField(default=datetime.datetime.now) #datetime.datetime.now() will set time to WHEN     script is run, don't use paranthesis
is_admin = BooleanField(default=False)

    class Meta:
        database = DATABASE
        order_by = ("-joined_at",)

    @classmethod
    def create_user(cls, username, email, password, admin=False):
        try:
            cls.create(
                username=username,
                email=email,
                password=generate_password_hash(password),
                is_admin=admin)
        except IntegrityError:
            raise ValueError("User already exists")

def initialize():
    DATABASE.connect()
    DATABASE.create_tables([User], safe=True)
    DATABASE.close()

2 Answers

Erik Malmberg
Erik Malmberg
1,465 Points

Lol, found the error.

{% if field.errors %}
{% for errors in field.errors %}
    <div class="notification error">{{ error }}</div>

Was the culprit. Used error variable for "errors"

Chris Howell
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Chris Howell
Python Web Development Techdegree Graduate 49,610 Points

Hi Erik Malmberg

So without seeing your forms.py and your template that serves up the page within your app. It is hard to say, but my safe assumption would be that the template that displays the form that you redirect back to when a form is invalid. Is either not pulling the errors out of the form or if you are using Flash messages to display a generic error for Form. Your register method looks like it has a Flash message for a valid form but not an invalid one.

Let me know if this helps you find the problem. And if you are running this inside Workspaces, if you Share the Workspace and provide the share link I can have a look. Otherwise if you cannot seem to find the answer, you will need to provide forms.py and the template file too so I dont have to make assumptions on what is there! :-)

Erik Malmberg
Erik Malmberg
1,465 Points

Hey Chris, sorry - didn't add them, added them now though. Can't find any typos or errors - maybe it has to do something with flask wtf forms being updated?

"FlaskWTFDeprecationWarning: "flask_wtf.Form" has been renamed to "FlaskForm" and will be removed in 1.0."