Im creating a flask app and the data is not stored when i click register after adding all the information. when I click the register button there are no any errors showing.
heres my routes.py
#app.route('/register', methods=['GET', 'POST'])
def register_page():
form = RegisterForm()
if form.validate_on_submit():
user_to_create = User(username=form.username.data,email=form.email.data,password_hash=form.password1.data)
db.session.add(user_to_create)
db.session.commit()
flash(f'Account created Successfully...! you are now logged in as {{ user_to_create.username }}',
category='success')
return redirect(url_for('topup_page'))
if form.errors != {}:
for error in form.errors.values():
flash(f'There was an error with creating the user{error}', category='danger')
return render_template('register.html', form=form)
here is my register.html file
<div class="col-6">
<div class="container">
<form method="POST" class="form-register">
<h2>Please Create Your Account</h2>
{{ form.hidden_tag() }}
<br>
{{ form.username.label()}}
{{ form.username(class="form-control", placeholder="User Name")}}
<br>
{{ form.email.label()}}
{{ form.email(class="form-control", placeholder="Email Address")}}
<br>
{{ form.password1.label()}}
{{ form.password1(class="form-control", placeholder="Password")}}
<br>
{{ form.password2.label()}}
{{ form.password2(class="form-control", placeholder="Confirm Password")}}
<br>
{{ form.submit(class="btn btn-lg btn-block btn-primary disabled") }}
<div class="checkbox mb-3">
<h6> Already have an account? Sign In
</h6>
</div>
</form>
</div>
here is my models.py file
#login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
class User(db.Model, UserMixin):
id = db.Column(db.Integer(), nullable=False, primary_key=True)
username = db.Column(db.String(20), nullable=False, unique=True)
email = db.Column(db.String(30), nullable=False, unique=True)
password = db.Column(db.String(60), nullable=False)
credit = db.relationship('Credit', backref='owner')
i think you need to add a name attribute to the inputs. Sorry if this is a wrong answer.I have not used flask in a long time.
I will show you sample code:
Template:
<form action="{{ url_for('app.update_view') }}" method="post"
enctype="multipart/form-data">
<input name="name1" placeholder='abc'>
<input name="name2" placeholder='xyz'>
<input name="name3" placeholder='123'>
<button type="submit" class="btn btn-primary">Register</button>
</form>
View:
#app.route('/path', methods=['POST', 'GET'])
#roles_required('admin,member') # doenst matter
def update_view():
try:
if request.method == 'POST':
name1 = request.form.get('name1')
name2 = request.form.get('name2')
name3 = request.form.get('name3')
if name1 is not None and name2 is not None:
YourModelNAme.create_classmethod(name1, name2, name3)
return render_template("directory_name/your_html.html")
except Exception as e:
return create_json_response(
{'message': 'Error->' + e.__str__()}, False, 201), 201
Model:
class YourModelNAme(db.Model, UserMixin):
name1 = db.Column(db.Integer(), nullable=False, primary_key=True)
name2 = db.Column(db.String(20), nullable=False, unique=True)
name3 = db.Column(db.String(60), nullable=False)
#classmethod
def create_classmethod(cls,name1,name2,name3):
your_model = YourModelNAme()
your_model.name1 = name1
...
db.session.add(your_model)
db.session.commit()
return your_model
Related
I am trying to make an upload form with Flask where the user needs to fill in the information needed, upload a photo, and also pick a category provided from the database by using QuerySelectField.
When I submit the form, nothing happens. It redirects me to the same page and the database is empty.
form.py
class UploadForm(FlaskForm):
title = StringField(label='Title:', validators=[DataRequired(), Length(min=2, max=30)])
organizer = StringField(label='Name:', validators=[DataRequired(), Length(min=2, max=30)],
render_kw={'readonly': True})
type = QuerySelectField(query_factory=choice_query, allow_blank=False, get_label='name')
description = StringField(label='description',validators=[DataRequired(), Length(min=1, max=250)])
address = StringField(label='address',validators=[DataRequired(), Length(min=1, max=50)])
file = FileField(label='file', validators=[DataRequired()])
price = IntegerField(label='Price:', validators=[DataRequired(), NumberRange(min=1, max=10)])
upload = SubmitField(label='Post')
model.py
class Event(db.Model):
__tablename__ = "event"
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(30), nullable=False)
price = db.Column(db.Integer(), nullable=False)
location = db.Column(db.String(50), nullable=False)
description = db.Column(db.String(1024), nullable=True, unique=True)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
type = db.Column(db.Integer(), db.ForeignKey('category.id'), nullable=False)
image_file = db.Column(db.String(20), nullable=True, default='default.jpg')
owner = db.Column(db.Integer(), db.ForeignKey('eventowners.id'), nullable=False)
reserver = db.relationship('Reservation', foreign_keys=[Reservation.reserved_id],
backref=db.backref('reserved', lazy='joined'), lazy='dynamic',
cascade='all, delete-orphan')
class Choice(db.Model):
__tablename__ = "category"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20), nullable=False)
event = db.relationship('Event', backref='events', lazy=True)
def __repr__(self):
return '[Choice {}]'.format(self.name)
class EventOwner(db.Model, UserMixin, USER):
__tablename__ = 'eventowners'
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
sub_type = db.Column(db.String, nullable=True, default=00)
events = db.relationship('Event', backref='eventowner', lazy=True)
follower = db.relationship('Follow', foreign_keys=[Follow.followed_id],
backref=db.backref('followed', lazy='joined'), lazy='dynamic',
cascade='all, delete-orphan')
routes.py
#app.route('/event/new', methods=['GET', 'POST'])
#login_required
def post_events():
if not os.path.exists('static/' + str(session.get('id'))):
os.makedirs('static/' + str(session.get('id')))
file_url = os.listdir('static/' + str(session.get('id')))
file_url = [str(session.get('id')) + "/" +
file for file in file_url]
formupload = UploadForm()
eventowner = current_user.id
formupload.organizer.data = eventowner
event = Event(owner=formupload.organizer.data)
if formupload.validate_on_submit():
event = Event(title=formupload.title.data,
type=formupload.type.data,
description=formupload.description.data,
price=formupload.price.data,
location=formupload.address.data,
image_file=photos.save(formupload.file.data,
name=str(session.get('id')) + '.jpg',))
db.session.add(event)
db.session.commit()
flash('Event Posted!')
return redirect(url_for('events_page'))
return render_template('post_event.html', formupload=formupload, event=event)
#app.route('/event', methods=['GET', 'POST'])
def events_page():
event = Event.query.order_by(Event.date_posted.desc()).all()
page = request.args.get('page', 1, type=int)
show_followed = False
if current_user.is_authenticated:
show_followed = bool(request.cookies.get('show_followed', ''))
if show_followed:
query = current_user.followed_posts
else:
query = Event.query
pagination = Event.query.order_by(Event.date_posted.desc()).paginate(page,
per_page=
current_app.config['FLASKY_POSTS_PER_PAGE'],
error_out=False
)
events = pagination.items
return render_template('event.html', events=events, pagination=pagination, show_followed=show_followed, event=event)
post_event.html
{% extends "base.html" %}
{% block content %}
<div class="breadcrumbs">
<div class="container">
<div class="row align-items-center">
<div class="col-lg-6 col-md-6 col-12">
<div class="breadcrumbs-content">
<h1 class="page-title">Events</h1>
</div>
</div>
<div class="col-lg-6 col-md-6 col-12">
<ul class="breadcrumb-nav">
<li>Home</li>
<li>Events</li>
</ul>
</div>
</div>
</div>
</div>
<form method="post" enctype="multipart/form-data" action="">
{{ form.hidden_tag() }}
<div class="search-form wow fadeInUp" data-wow-delay=".7s" style="background: none; margin-top:50px; margin-bottom:50px">
<div class="form-group">
<label for="Title" style="color: black" >Event Title</label>
{{ formupload.label }} {{ formupload.title(class='form-control' )}}
</div>
<div class="form-group col-md-6">
<label for="organizer" style="color: black" >Organizer</label>
<!-- <input type="text" class="form-control" id="Organizer"> -->
<div> {{ formupload.label }} </div>
<div> {{ formupload.organizer._value()}}</div>
</div>
<div class="form-group col-md-4">
<label for="inputState" style="color: black" >Type</label>
{{ formupload.csrf_token }}
{{ formupload.type }}
<ul>
{% for error in formupload.type.errors %}
<li style="color:red;">{{ error }}</li>
{% endfor %}
</ul>
</div>
<div class="form-group col-md-6">
<label for="description" style="color: black" >Description</label>
{{ formupload.label }} {{ formupload.description(class='form-control' )}}
<!--<input type="text" class="form-control" id="desc"> -->
</div>
<div class="form-group col-md-6">
<label for="starting_price" style="color: black" >Starting Price</label>
{{ formupload.label }} {{ formupload.price(class='form-control' )}}
<!-- <input type="text" class="form-control" id="Price"> -->
</div>
<div class="form-group">
<label for="inputAddress2" style="color: black" >Address</label>
<!-- <input type="text" class="form-control" id="Address" placeholder="Corso Duca degli Abruzzi, 24"> -->
{{ formupload.label }} {{ formupload.address(class='form-control' )}}
</div>
<div class="form-group">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="gridCheck">
<label class="form-check-label" for="gridCheck" style="color: black">
I agree to the Terms of Service and Privacy Policy
</label>
</div>
</div>
<div class="form-group">
{{ formupload.file.label }}
{{ formupload.file }}
{{ formupload.upload }}
{% for file in filelist %}
<img class="upload-img" src='{{ url_for("static",filename=file) }}' alt="">
{% endfor %}
</div>
<div class="form-group">
{{ form.submit(class="btn btn--primary") }}
</div>
</div>
</form>
{% include "bottom.html" %}
<script src="{{ url_for('static',filename='js/bootstrap.min.js') }}"></script>
<script src="{{ url_for('static',filename='js/wow.min.js') }}"></script>
<script src="{{ url_for('static',filename='js/tiny-slider.js') }}"></script>
<script src="{{ url_for('static',filename='js/glightbox.min.js') }}"></script>
<script src="{{ url_for('static',filename='js/main.js') }}"></script>
{% endblock %}
Unless you're submitting a form via Javascript, a form submission will get sent to the value in action attribute of the form. Yours is blank which is why the page is simply reloaded.
<form method="post" enctype="multipart/form-data" action="">
Update:
You need to specify a route in the action attribute e.g. /event/new or /event depending on which one is expected to process the form. If it's none of the above, then you have to define a route server side (your flask code) and specify the route in the action attribute.
I have seen a few similar questions here, but none of the solutions seem to apply here(the problem is usually that it lacks a csrf token, which is not the case here).
I have a form with four fields- 3 drop down lists with SelectField and one StringField- built using flask wtforms. I tried adding an edit feature to this, which uses the same HTML template, but this it isn't getting validated(not entering the form.validate_on_submit section). This is the code for the function:
#app.route('/movements/<int:movement_id>/edit', methods=['GET', 'POST'])
def edit_movement(movement_id):
movement = Movement.query.get_or_404(movement_id)
form = MovementForm()
if form.validate_on_submit():
product = Product.query.filter_by(id=form.product.data).first()
from_location = Location.query.filter_by(id=form.from_location.data).first()
to_location = Location.query.filter_by(id=form.to_location.data).first()
if int((Balance.query.filter_by(product = product.name).filter_by(location = from_location.name).first()).balance) < int(form.quantity.data) and from_location.name != "":
flash("Invalid movement. Quantity of the product is insufficient.")
else:
movement.product_id = product.id
movement.product = product.name
movement.from_location_id = from_location.id
movement.from_location = from_location.name
movement.to_location_id = to_location.id
movement.to_location = to_location.name
movement.quantity = form.quantity.data
db.session.commit()
flash('The product movement has been edited!', 'success')
return redirect(url_for('movements'))
elif request.method == 'GET':
form.product.choices = [(product.id,product.name) for product in Product.query.all()]
form.from_location.choices = [(location.id,location.name) for location in Location.query.all()]
form.to_location.choices = [(location.id,location.name) for location in Location.query.all()]
form.quantity.data = movement.quantity
edit_button = True
return render_template('movements.html',form=form, edit_button=edit_button)
This is the code for the form:
class MovementForm(FlaskForm):
product = SelectField("Product", choices = [])
from_location = SelectField("From Location", choices = [], coerce=int)
to_location = SelectField("To Location", choices = [], coerce=int)
quantity = StringField("Quantity", validators=[DataRequired()])
add_movement = SubmitField("Add Movement")
And this is the model for the table:
class Movement(db.Model):
id = db.Column(db.Integer, primary_key=True)
product_id = db.Column(db.Integer, db.ForeignKey('product.id'), nullable=False)
product = db.Column(db.String(50), nullable=False)
from_location_id = db.Column(db.Integer, db.ForeignKey('location.id'))
from_location = db.Column(db.String(50))
to_location_id = db.Column(db.Integer, db.ForeignKey('location.id'))
to_location = db.Column(db.String(50))
quantity = db.Column(db.Integer, nullable=False)
timestamp = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
The HTML code for the form:
<form action="" method="POST">
{{ form.csrf_token }}
{{ form.product.label }}
{{ form.product }}
{{ form.from_location.label }}
{{ form.from_location }}
{{ form.to_location.label }}
{{ form.to_location }}
{{ form.quantity.label }}
{{ form.quantity }}
{% if edit_button %}
<input type="submit" value="Edit Movement">
{% else %}
{{ form.add_movement }}
{% endif %}
</form>
validate_on_submit is a convenient function that combines a check for whether the form was submitted (i.e., a POST, PUT, PATCH, or DELETE) with call to form.validate. If validation fails, the dictionary held byform.errors will get populated with useful information.
A useful step to debug your problem would be to log (print) the contents of form.errors if validate_on_submit returns False.
The form.errors in your code is as follows:
{'product': ['Not a valid choice'], 'from_location': ['Not a valid choice'], 'to_location': ['Not a valid choice']}
So it is reasonable for the validate_on_submit to return False.
If you comment out these fields and leave only the quantity it should work. The following changes worked for me and I managed to update the quantity in the DB. If it works also for you then you could try to uncomment each field and debug further.
Change the form to:
class MovementForm(FlaskForm):
quantity = StringField("Quantity", validators=[DataRequired()])
add_movement = SubmitField("Add Movement")
and the route to:
#app.route('/movements/<int:movement_id>/edit', methods=['GET', 'POST'])
def edit_movement(movement_id):
movement = Movement.query.get_or_404(movement_id)
form = MovementForm()
if form.validate_on_submit():
movement.quantity = form.quantity.data
db.session.commit()
flash('The product movement has been edited!', 'success')
return redirect(url_for('movements'))
elif request.method == 'GET':
form.quantity.data = movement.quantity
print(form.errors)
edit_button = True
return render_template('movements.html', form=form, edit_button=edit_button)
Change the template to:
<form action="" method="POST">
{{ form.csrf_token }}
{{ form.quantity.label }}
{{ form.quantity }}
{% if edit_button %}
<input type="submit" value="Edit Movement">
{% else %}
{{ form.add_movement }}
{% endif %}
</form>
Update:
The issue you are facing is described here.
Please try the following and if it works as expected then set similarly the remaining fields (it worked for me and I managed to update the quantity and the from_location/id in the DB):
the form:
class MovementForm(FlaskForm):
fromloc = [(location.id,location.name) for location in Location.query.all()]
from_location_id = SelectField("From Location ID", choices = fromloc, coerce=int)
quantity = StringField("Quantity", validators=[DataRequired()])
add_movement = SubmitField("Add Movement")
the route:
#app.route('/movements/<int:movement_id>/edit', methods=['GET', 'POST'])
def edit_movement(movement_id):
movement = Movement.query.get_or_404(movement_id)
form = MovementForm()
if form.validate_on_submit():
movement.from_location_id = form.from_location_id.data
movement.from_location = (Location.query.filter_by(id = form.from_location_id.data).first()).name
movement.quantity = form.quantity.data
db.session.commit()
flash('The product movement has been edited!', 'success')
return redirect(url_for('movements'))
elif request.method == 'GET':
form.from_location_id.choices = [(location.id,location.name) for location in Location.query.all()]
form.quantity.data = movement.quantity
print(form.errors)
edit_button = True
return render_template('movements.html', form=form, edit_button=edit_button)
the template:
<form action="" method="POST">
{{ form.csrf_token }}
{{ form.from_location_id.label }}
{{ form.from_location_id }}
{{ form.quantity.label }}
{{ form.quantity }}
{% if edit_button %}
<input type="submit" value="Edit Movement">
{% else %}
{{ form.add_movement }}
{% endif %}
</form>
I'm still not quite sure why my form wasn't validating, but my function started working after I replaced if form.validate_on_submit() with if request.method == 'POST'.
How would I update the current users firstname and lastnames in my Flask-SQLAlchemy database?
I have tried to use the following code based off of the flask-sqlalchemy documentation - however, it only commits the update for the email field and does not update the record for either the firstname or lastname fields.
# views.py
#users.route("/account", methods=['GET', 'POST'])
#login_required
def account():
form = UpdateUserForm()
if form.validate_on_submit():
current_user.firstname = form.firstname.data
current_user.lastname = form.lastname.data
current_user.email = form.email.data
db.session.commit()
return redirect(url_for('users.account'))
elif request.method == 'GET':
form.firstname.data = current_user.firstname
form.lastname.data = current_user.lastname
form.email.data = current_user.email
return render_template('account.html', form=form)
#forms.py
class UpdateUserForm(FlaskForm):
email = StringField('Email',validators=[InputRequired(message = 'Enter a valid email'),Email()])
firstname = StringField('First Name',validators=[InputRequired(message = 'Enter your first name')])
lastname = StringField('Last Name',validators=[InputRequired(message = 'Enter your last name')])
submit = SubmitField('Update')
def validate_email(self,email):
if User.query.filter_by(email=email.data).first():
raise ValidationError('This email has been registered already!')
# Summarized Template & Form Submission
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="account" role="tabpanel" aria-labelledby="account-tab">
<div class="col-5">
</div>
<div class="col-sm-12 col-md-7">
<form method="post" action="" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<div class="form-group">
<label class="small mb-0">{{ form.firstname.label }}</label>
{{ form.firstname(class="form-control") }}
</div>
<div class="form-group">
<label class="small mb-0">{{ form.lastname.label }}</label>
{{ form.lastname(class="form-control") }}
</div>
<div class="form-group">
<label class="small mb-0">{{ form.email.label }}</label>
{{ form.email(class="form-control") }}
</div>
{{ form.submit(class="btn btn-primary") }}
</form>
</div>
</div>
# Model.py
class User(db.Model, UserMixin):
__tablename__ = 'users'
id = db.Column(db.Integer,primary_key=True)
selected_theme = db.Column(db.String(64),nullable=False,default='default')
email = db.Column(db.String(64),unique=True,index=True)
fullname = db.Column(db.String(64))
firstname = db.Column(db.String(64))
lastname = db.Column(db.String(64))
password_hash = db.Column(db.String(128))
def __init__(self,email,fullname,password, firstname, lastname):
self.email = email
self.fullname = fullname
self.firstname = firstname
self.lastname = lastname
self.password_hash = generate_password_hash(password)
def check_password(self,password):
return check_password_hash(self.password_hash,password)
def __repr__(self):
return f"Username {self.username}"
Sorry, I can't find a mistake. The following code works for me. Even if there is no real difference to yours, it is worth trying.
class UpdateUserForm(FlaskForm):
email = StringField(
'Email',
validators=[
# InputRequired is deprecated and replaced by DataRequired
DataRequired(message = 'Enter a valid email'),
Email()
]
)
firstname = StringField(
'First Name',
validators=[
DataRequired(message = 'Enter your first name')
]
)
lastname = StringField(
'Last Name',
validators=[
DataRequired(message = 'Enter your last name')
]
)
submit = SubmitField('Update')
def validate_email(self, email):
if User.query.filter_by(email=email.data).first():
raise ValidationError('This email has been registered already!')
#users.route("/account", methods=['GET', 'POST'])
#login_required
def account():
# You can forward your current data to the form here
form = UpdateUserForm(request.form, obj=current_user)
if form.validate_on_submit():
current_user.firstname = form.firstname.data
current_user.lastname = form.lastname.data
current_user.email = form.email.data
db.session.commit()
return redirect(url_for('users.account'))
return render_template('account.html', **locals())
<form method="POST">
{{ form.csrf_token }}
<div class="form-group">
{{ form.email.label() }}
{{ form.email(class='form-control') }}
{% if form.email.errors: %}
<div class="invalid-feedback">
{{ form.email.errors[0] }}
</div>
{% endif %}
</div>
<div class="form-group">
{{ form.firstname.label() }}
{{ form.firstname(class='form-control') }}
{% if form.firstname.errors: %}
<div class="invalid-feedback">
{{ form.firstname.errors[0] }}
</div>
{% endif %}
</div>
<div class="form-group">
{{ form.lastname.label() }}
{{ form.lastname(class='form-control') }}
{% if form.lastname.errors: %}
<div class="invalid-feedback">
{{ form.lastname.errors[0] }}
</div>
{% endif %}
</div>
{{ form.submit(class='btn btn-primary') }}
</form>
Thanks for your help! Was able to resolve my issue by including the following updated to ignore the email submission if it is unchanged (I think it was recognized as a duplicate record and preventing unique value). This little addition seems to resolve.
def validate_email(self,email):
if User.query.filter_by(email=email.data).first() and email.data != current_user.email:
raise ValidationError('Email has been already been registered.')
This flask app is properly prompting for username and password- but according to the log files, returning the route /NONE despite that issue, the session seems to be valid and other #login_required routes can be accessed. Any ideas as to what is going on would be appreciated.
Login Template: login.html
{% extends "bootstrap/base.html" %}
{% block content %}
<div class="container">
<div class="row">
<form class="form-signin" action="/logmein" method="POST">
<h2 class="form-signin-heading"> PCBevo Login</h2>
<div class="col-2">
<label for="username" class="sr-only">Username</label>
<input type="text" id="username" class="form-control" placeholder="username" name="username" required autofocus>
</div>
<div class="col-3">
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" id="inputPassword" class="form-control" placeholder="password" name="password" required>
</div>
<div class="col-4">
<button class="btn btn-lg btn-primary btn-block" type="submit" value="Submit">Sign in</button>
</div>
</form>
</div>
</div> <!-- /container -->
{% endblock %}
Below is the SQLAlchemy User Model:
class User(UserMixin, db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(254), unique=True)
email = db.Column(db.String(50), unique=True)
password = db.Column(db.String(80))
groups = db.Column(db.String(80))
def __init__(self, username, email, password, groups):
self.username = username
self.email = email
self.password = password
self.groups = groups if isinstance(groups, str) else ','.join(groups)
def __repr__(self):
clsname = self.__class__.__name__
return "{}({}) ".format(clsname, self.username)
def is_developer(self):
return isinstance(self.groups, str) and 'dev' in self.groups.split(',')
Selected attributes for app setup of login_manager and problem routes:
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
#login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
#app.route('/login')
def login():
session['next'] = request.args.get('next')
return render_template('login.html')
#app.route('/logmein', methods=['POST'])
def logmein():
username = request.form['username']
password = request.form['password']
user = User.query.filter_by(username=username).first()
if not user:
return '<h1>User not found!</h1>'
stored_password = user.password
if check_password_hash(stored_password, password):
login_user(user)
try:
return redirect(session['next'])
except KeyError:
return '<h1>You are now logged in!</h1>'
else:
return '<h1>Wrong password!</h1>'
Check session['next'] before return redirect(session['next']).
It can be empty if you will run /login instead of /login?next=some_url
because request.args.get('next') will return default value None
But you can use own default value ie. main page "/"
request.args.get('next', "/" )
When I submit my form from webpage, I am not able to commit. Flashing data I need, I see they're there and correct, but something fails when committing. I am sure I am making a mistake somewhere because mostly commit are working except two. This is one of the two that is not working.
Models:
class Feedback(db.Model):
__tablename__ = 'feedback'
id = db.Column(db.Integer, primary_key = True)
rate = db.Column(db.Integer)
comment = db.Column(db.Text())
sender_id = db.Column(db.Integer)
receiver_id = db.Column(db.Integer)
Forms:
class LeaveFeedbackForm(Form):
rate = IntegerField('Rate', validators = [DataRequired(),
NumberRange(min = 1, max = 5, message = 'Rates admitted are only 1,2,3,4,5')])
comment = TextAreaField('Comment', validators = [DataRequired()])
submit = SubmitField('Submit')
Views:
#app.route('/leave_feedback/<sender>/<receiver>', methods = ['GET', 'POST'])
def leave_feedback(receiver, sender):
form = LeaveFeedbackForm()
rec = int(receiver)
sen = int(sender)
if form.validate_on_submit():
feedback = Feedback( rate = form.rate.data,
comment = form.comment.data,
receiver_id = rec,
sender_id = sen
)
db.session.add(feedback)
db.session.commit()
flash('Feedback Left Correctly.')
return redirect(url_for('index'))
flash(form.rate.data)
flash(form.comment.data)
flash(rec)
flash(sen)
return render_template('leave_feedback.html', receiver_id = receiver, sender_id = sender, form = form)
html:
{% block content %}
<div class="row">
<div class="large-6 columns">
<h1>Leave Feedback</h1>
</div>
</div>
<form action="" method="post" name="leavefeedback">
<div class="row">
<div class="large-6 columns">
<label>Rate
{{ form.rate }}
</label>
</div>
</div>
<div class="row">
<div class="large-6 columns">
<label>Comment
{{ form.comment }}
</label>
</div>
</div>
<div class="row">
<div class="large-6 columns">
<input class="button radius" type="submit" value="Leave Feedback">
</div>
</div>
</form>
{% endblock %}
You should add an else statement:
if form.validate_on_submit():
...
else:
for error in form.errors.itervalues():
flash(error[0])
Then you will get an error message from form.
I figured out my mistake, I simply forgot in my form:
{{ form.hidden_tag() }}