Reputation: 194
I posted this question earlier but it was then linked to a similar question which don't provide the required solution and was then closed for answering.
So I have created a Flask Application that tracks the movement of products from one location to another while I make movements via the Flask App the form doesn't get validated I tried adding {{ form.hidden_tag() }}
and {{ form.csrf_token }}
to the html file that takes input from the user.
If I run this application from the terminal on my command line the form is validated and gets added to the database but if I run the flask app and submit the form in the browser it doesn't.
here is my code for the same
class MovementForm(FlaskForm):
to_location = SelectField('To Location', coerce=int)
from_location = SelectField('From Location', coerce=int)
product = SelectField('Product')
quantity = IntegerField('Quantity')
add_movement = SubmitField('Add Movement')
@app.route('/movements',methods=["GET","POST"])
def add_movements():
form = MovementForm()
form.to_location.choices = [(location.id, location.location_name) for location in Location.query.all()]
form.from_location.choices = [(location.id, location.location_name) for location in Location.query.all()]
form.product.choices = [(product.id, product.product_name) for product in Product.query.all()]
form.from_location.choices.insert(0, (0, 'None'))
if form.validate_on_submit():
new_movement = Movement(to_location_id=form.to_location.data, from_location_id=form.from_location.data, product_id=form.product.data, quantity=form.quantity.data)
db.session.add(new_movement)
db.session.commit()
flash('Product has been moved!', 'success')
return redirect(url_for('add_movements'))
return render_template('add_movements.html', form=form)
Here is my html file
<form action="/movements" method="post">
{{ form.hidden_tag() }}
{{ form.csrf_token }}
<div class="row">
<div class="form-group col">
{{ form.from_location.label(class="form-control-label") }}
{{ form.from_location(class="form-control form-control-lg") }}
</div>
<div class="form-group col">
{{ form.to_location.label(class="form-control-label") }}
{{ form.to_location(class="form-control form-control-lg") }}
</div>
</div>
<div class="row">
<div class="form-group col">
{{ form.product.label(class="form-control-label") }}
{{ form.product(class="form-control form-control-lg") }}
</div>
<div class="form-group col">
{{ form.quantity.label(class="form-control-label") }}
{{ form.quantity(class="form-control form-control-lg") }}
</div>
</div>
<div class="form-group">
{{ form.add_movement(class="btn btn-outline-info") }}
</div>
</form>
What's wrong here?
Upvotes: 1
Views: 253
Reputation: 7735
Try to remove to change in the HTML form the form's action.
<form action="" method="post">
{{ form.hidden_tag() }}
{{ form.csrf_token }}
<div class="row">
<div class="form-group col">
{{ form.from_location.label(class="form-control-label") }}
{{ form.from_location(class="form-control form-control-lg") }}
</div>
<div class="form-group col">
{{ form.to_location.label(class="form-control-label") }}
{{ form.to_location(class="form-control form-control-lg") }}
</div>
</div>
<div class="row">
<div class="form-group col">
{{ form.product.label(class="form-control-label") }}
{{ form.product(class="form-control form-control-lg") }}
</div>
<div class="form-group col">
{{ form.quantity.label(class="form-control-label") }}
{{ form.quantity(class="form-control form-control-lg") }}
</div>
</div>
<div class="form-group">
{{ form.add_movement(class="btn btn-outline-info") }}
</div>
</form>
Does this solve the issue?
Also What I suggest you is to add the Flash message into the HTML, because I see that once the Form is submitted it returns back to the 'add_movements' function. Therefore add this:
<div>
{% for msg in get_flashed_messages%}
<h1>{{msg}}</h1>
{% endfor %}
</div>
<form action="" method="post">
{{ form.hidden_tag() }}
{{ form.csrf_token }}
<div class="row">
<div class="form-group col">
{{ form.from_location.label(class="form-control-label") }}
{{ form.from_location(class="form-control form-control-lg") }}
</div>
<div class="form-group col">
{{ form.to_location.label(class="form-control-label") }}
{{ form.to_location(class="form-control form-control-lg") }}
</div>
</div>
<div class="row">
<div class="form-group col">
{{ form.product.label(class="form-control-label") }}
{{ form.product(class="form-control form-control-lg") }}
</div>
<div class="form-group col">
{{ form.quantity.label(class="form-control-label") }}
{{ form.quantity(class="form-control form-control-lg") }}
</div>
</div>
<div class="form-group">
{{ form.add_movement(class="btn btn-outline-info") }}
</div>
#EDIT
I noticed that something is missing in the product field once coerce in missing:
class MovementForm(FlaskForm):
to_location = SelectField('To Location', coerce=int)
from_location = SelectField('From Location', coerce=int)
product = SelectField('Product', coerce=int)
quantity = IntegerField('Quantity')
add_movement = SubmitField('Add Movement')
EDIT #2
In case you run in this kind of issues (which happens all the time) I suggest you to add a print statements and a If/Else clause as well. This will dramatically help you where the issue is ( The issue on your type of problem you posted is that you 'don't see it') and will give you 'eyes.'
For example this is what I would have done:
@app.route('/movements',methods=["GET","POST"])
def add_movements():
form = MovementForm()
form.to_location.choices = [(location.id, location.location_name) for
location in Location.query.all()]
form.from_location.choices = [(location.id, location.location_name)
for location in Location.query.all()]
form.product.choices = [(product.id, product.product_name) for product
in Product.query.all()]
form.from_location.choices.insert(0, (0, 'None'))
if form.validate_on_submit():
print('Form Ok') #if you see the 'Form ok' to see if is validated
new_movement = Movement(to_location_id=form.to_location.data,
from_location_id=form.from_location.data,
product_id=form.product.data, quantity=form.quantity.data)
db.session.add(new_movement)
db.session.commit()
flash('Product has been moved!', 'success')
return redirect(url_for('add_movements'))
else:
print('Form Not Ok') #If you see this printed then you see that
#is not validated
return render_template('add_movements.html', form=form)
Upvotes: 1