Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialrshap
12,433 PointsProblems with the "validate_on_submit()" function (I think...)
I'm having problems with the code that I've been writing along with the videos. Every time that I register or submit a new post the page just refreshes (the else of the if form.validate_on_submit() happens). Maybe some of the names of the imported files or the validators has been changed? Please help Kenneth Love...
rshap
12,433 Pointsfrom flask import Flask, g, render_template, flash, redirect, url_for
from flask_bcrypt import check_password_hash
from flask_login import (LoginManager, login_user, logout_user,
login_required, current_user)
import forms
import models
DEBUG = True
PORT = 8000
HOST = '127.0.0.1'
app = Flask(__name__)
app.secret_key = 'isbfF74tG75 HbgX-<x9et*b/.hbbuh#-@ib5G'
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 the database before each request.
"""
g.db = models.DATABASE
g.db.connect()
g.user = current_user
@app.after_request
def after_request(response):
"""Close the database connection after each request.
"""
g.db.close()
return response
# Doesn't work
@app.route('/register', methods = ('GET', 'POST'))
def register():
form = forms.RegistarationForm()
if form.validate_on_submit():
flash("Registration successful!", "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('/login', methods = ('GET', 'POST'))
def login():
form = forms.LoginForm()
if form.validate_on_submit():
try:
user = models.User.get(models.User.email == form.email.data)
except models.DoesNotExist:
flash("The email and password you've entered don't match." , "error")
else:
if check_password_hash(user.password, form.password.data):
login_user(user)
flash("You've been logged in successfully.", "success")
return redirect(url_for('index'))
else:
flash("The email and password you've entered don't match." , "error")
return render_template('login.html', form = form)
@app.route('/logout')
@login_required
def logout():
logout_user()
flash("You've been logged out.", "success")
return redirect(url_for('index'))
# Doesn't work
@app.route('/new_post', methods = ('GET', 'POST'))
@login_required
def post():
post = forms.PostForm()
if post.validate_on_submit():
models.Post.create(
user = g.user._get_current_object(),
content = post.content.data.strip()
)
flash("Message posted successfully!", "success")
return redirect(url_for('index'))
return render_template('post.html', form = post)
@app.route('/stream')
@app.route('/stream/<username>')
def stream(username = None):
template = 'stream.html'
if username and username != current_user.username:
user = models.User.select().where(models.User.username ** username).get()
stream = user.posts.limit(100)
else:
user = current_user
stream = current_user.get_stream().limit(100)
if username:
template = 'user_stream.html'
return render_template(template, stream = stream, user = user)
@app.route('/')
def index():
stream = models.Post.select().limit(100)
return render_template('stream.html', stream = stream)
if __name__ == '__main__':
models.initialize()
try:
models.User.create_user(
username = 'superuser',
email = 'superuser@gmail.com',
password = 'password',
is_admin = True
)
except ValueError:
pass
app.run(debug = DEBUG, port = PORT, host = HOST)
I pasted here my code. Sorry and thank you :)
Chris Jones
Java Web Development Techdegree Graduate 23,933 PointsThanks for sharing the code. This helps, but I have questions that seeing the rest of your workspace will help answer. Can you create a snapshot of your workspace by following the instructions in this post:
https://teamtreehouse.com/community/workspace-snapshots
Thank you!
5 Answers
Chris Jones
Java Web Development Techdegree Graduate 23,933 PointsI'd like to see your RegistrationForm
class and PostForm
class. The Flask documentation for Form classes shows that these types of classes take a Form parameter. However, you're not passing anything to your RegistrationForm
and PostForm
constructors in the code you shared. So, essentially you're creating a blank form object, which may not pass the validate_on_submit()
method, which wouldn't post your form data and would just redirect you back to the login.html
or post.html
pages.
But having a snapshot of your workspace (see my last comment on how to make a snapshot) will help determine if I'm correct in my thinking.
rshap
12,433 Pointshttps://w.trhou.se/q9brwqzdiw A few of the package names I've changed from the videos because the python program on my pc told me to... And thanks again :)
Chris Jones
Java Web Development Techdegree Graduate 23,933 PointsThanks!
Yeah, your RegistrationForm
class takes a FlaskForm parameter, but you're not passing anything to it in app.py
. The Flask documentation shows that you need to pass it request.form
. If you try passing request.form
to the constructor, does that solve your issue?
The same thing is happening with the PostForm
class.
class RegistarationForm(FlaskForm): #class constructor requires a FlaskForm parameter.
username = StringField(
'Username',
validators = [
DataRequired(),
Regexp(
r'^[a-zA-Z0-9]+$',
message = "The username should be one word with letters,"
+ " numbers, and underscores only."
),
name_exists
]
)
email = StringField(
'E-mail',
validators = [
DataRequired(),
Email(),
email_exists
]
)
password = PasswordField(
'Password',
validators = [
DataRequired(),
Length(min = 5, message = 'Your password must be at least 5 characters long.'),
]
)
password2 = PasswordField(
'Confirm Password',
validators = [
DataRequired(),
EqualTo('password', message = 'The two passwords must match.')
]
)
class PostForm(FlaskForm):
content = TextAreaField("Type your post into here", validators = [DataRequired()])
rshap
12,433 PointsI'm sorry, but I'm confused, where you placed your comment, isn't that the place for inheritance?
Chris Jones
Java Web Development Techdegree Graduate 23,933 PointsOh no, I'm sorry, total lapse on my part. Thanks for pointing out my mistake! Admittedly, I don't spend a lot of time with Python :)!
Looks like the problem isn't your form classes. But, when I look at the Flask documentation I see that you're supposed to pass the request's form to the RegistrationForm
(see below):
@app.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm(request.form) # The request's form is passed to RegistrationForm.
if request.method == 'POST' and form.validate():
user = User(form.username.data, form.email.data,
form.password.data)
db_session.add(user)
flash('Thanks for registering')
return redirect(url_for('login'))
return render_template('register.html', form=form)
However, you're not passing the request's form (see below):
# Doesn't work
@app.route('/register', methods = ('GET', 'POST'))
def register():
form = forms.RegistarationForm() # request's form is NOT passed to RegistrationForm.
if form.validate_on_submit():
flash("Registration successful!", "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)
I also see this in the link to the documentation:
Things to remember:
1) create the form from the request form value if the data is submitted via the HTTP POST method and args if the data is submitted as GET.
2) to validate the data, call the validate() method, which will return True if the data validates, False otherwise.
3) to access individual values from the form, access form.<NAME>.data.
rshap
12,433 PointsI'm sorry, but the registration does work, but just the flash() function doesn't. Although the post() function still doesn't work at all (the verify_on_submit() if) and the flash() function in general.
Chris Jones
Java Web Development Techdegree Graduate 23,933 PointsSo, a new user is being created in the register
method??
rshap
12,433 PointsYes, a new user is created and then I can use it for anything but post. Plus the flash() function doesn't work at all (but doesn't give out any error either)...
Chris Jones
Java Web Development Techdegree Graduate 23,933 PointsChris Jones
Java Web Development Techdegree Graduate 23,933 PointsHi roeespaira,
Could you post a link to your workspace or at least the code that you reference (the form.validate_on_submit method)?
Thanks!