I have been trying to incorporate wtforms validators inside 2 forms I have on my index.html(this is a Uni assignment). Everything worked well before I did anything, but security was very bad. After I have inserted some wtform validators, everything works OK. But usability is quite bad. If I get an error whilst filling out one of the forms, I get error messages not only in the form I was writing stuff in, but also in the other separate form on index.html.
I suspect it has something with the way the assignment is set up. Like I said, I have 2 forms on my index.html. In a separate python file, where all the forms are configured, there is the following setup (where LoginForm and RegisterForm are the two forms on index.html):
class LoginForm(FlaskForm):
#more code here
class RegisterForm(FlaskForm):
#more code here
class IndexForm(FlaskForm):
login = FormField(LoginForm)
register = FormField(RegisterForm)
My first thought was to just delete the IndexForm code (and obviously update the code everywhere else where it was needed). I can´t see why the class IndexForm has to wrap the other 2. But that didn´t work out. So I suspect there is a reason why it´s set up the way it is. But how can I make RegisterForm and LoginForm behave such that a validation error in one of them, doesn´t trigger error messages in the other? I have inserted more verbose code below, if that could be of any help.
forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField, FormField, TextAreaField, FileField
from wtforms.fields.html5 import DateField
from wtforms.validators import InputRequired, Length, EqualTo, NoneOf
# defines all forms in the application, these will be instantiated by the template,
# and the routes.py will read the values of the fields
# TODO: Add validation, maybe use wtforms.validators??
# TODO: There was some important security feature that wtforms provides, but I don't remember what; implement it
#invalidInput = [ADD THINGS HERE]
class LoginForm(FlaskForm):
username = StringField('Username', render_kw={'placeholder': 'Username'}, validators=[InputRequired()])
password = PasswordField('Password', render_kw={'placeholder': 'Password'}, validators=[InputRequired()])
remember_me = BooleanField('Remember me') # TODO: It would be nice to have this feature implemented, probably by using cookies
submit = SubmitField('Sign In')
class RegisterForm(FlaskForm):
first_name = StringField('First Name', render_kw={'placeholder': 'First Name'}, validators=[InputRequired(), NoneOf(invalidInput, message="Invalid input")])
last_name = StringField('Last Name', render_kw={'placeholder': 'Last Name'}, validators=[InputRequired()])
username = StringField('Username', render_kw={'placeholder': 'Username'}, validators=[
InputRequired(), Length(min=5, max=50, message="Must be between 5 and 50 characters")])
password = PasswordField('Password', render_kw={'placeholder': 'Password'}, validators=[
InputRequired(), Length(min=8, max=50, message="Must be between 8 and 50 characters"), EqualTo('confirm_password', message='Passwords must match')])
confirm_password = PasswordField('Confirm Password', render_kw={'placeholder': 'Confirm Password'}, validators=[
InputRequired(), Length(min=8, max=50, message="Must be between 8 and 50 characters")])
submit = SubmitField('Sign Up')
class IndexForm(FlaskForm):
login = FormField(LoginForm)
register = FormField(RegisterForm)
routes.py
from app import app, query_db
from app.forms import IndexForm, PostForm, FriendsForm, ProfileForm, CommentsForm
from datetime import datetime
import os
#############################
from flask_wtf import FlaskForm
from wtforms import (StringField, PasswordField, SubmitField, TextAreaField, IntegerField, BooleanField, RadioField)
from wtforms.validators import InputRequired, Length
# this file contains all the different routes, and the logic for communicating with the database
# home page/login/registration
@app.route('/', methods=['GET', 'POST'])
@app.route('/index', methods=['GET', 'POST'])
def index():
form = IndexForm()
if form.login.validate_on_submit() and form.login.is_submitted() and form.login.submit.data:
user = query_db('SELECT * FROM Users WHERE username="{}";'.format(form.login.username.data), one=True)
print("user is ", user)
if user == None:
flash('Sorry, this user does not exist!')
elif user['password'] == form.login.password.data:
return redirect(url_for('stream', username=form.login.username.data))
else:
flash('Sorry, wrong password!')
elif form.register.validate_on_submit() and form.register.is_submitted() and form.register.submit.data:
flash("New user registered!")
query_db('INSERT INTO Users (username, first_name, last_name, password) VALUES("{}", "{}", "{}", "{}");'.format(form.register.username.data, form.register.first_name.data,
form.register.last_name.data, form.register.password.data))
print(form.register.username.data)
print(form.register.password.data)
return redirect(url_for('index'))
return render_template('index.html', title='Welcome', form=form)
index.html
{% import "bootstrap/wtf.html" as wtf %}
{% block content %}
<div class="jumbotron jumbotron-fluid">
<div class="container">
<h1 class="display-4">Social Insecurity</h1>
<p class="lead">The social network for the insecure™</p>
</div>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 col-lg-6">
<div class="card text-center">
<div class="card-header">
Sign In
</div>
<div class="card-body">
<h5 class="card-title">Access an existing profile</h5>
<form action="" method="POST" novalidate>
{{ wtf.form_field(form.login.username) }}
{{ wtf.form_field(form.login.password) }}
{{ wtf.form_field(form.login.remember_me) }}
{{ wtf.form_field(form.login.submit, class="btn btn-primary") }}
</form>
</div>
</div>
</div>
<div class="col-sm-12 col-lg-6">
<div class="card text-center">
<div class="card-header">
Register
</div>
<div class="card-body">
<h5 class="card-title">Create a new profile</h5>
<form action="", method="POST" novalidate>
{{ wtf.form_field(form.register.csrf_token) }}
{{ wtf.form_field(form.register.first_name) }}
{{ wtf.form_field(form.register.last_name) }}
{{ wtf.form_field(form.register.username) }}
{{ wtf.form_field(form.register.password) }}
{{ wtf.form_field(form.register.confirm_password) }}
{{ wtf.form_field(form.register.submit, class="btn btn-primary") }}
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}```
Solved it by removing the validators from LoginForm in forms.py. No need to validate these fields, if I have already validated them when creating a new user.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.