Put form input in variable (Python, Flask) - python

I am trying to retrieve the form input and put it in my variable (test), this is what I tried:
from flask import Flask, redirect, render_template, request, url_for
import random
app = Flask(__name__)
app.config["DEBUG"] = True
vraag = "Wat is een barkie?"
ans = ['€10', '€50', '€100', '€1000']
#app.route("/")
def Q1():
random.shuffle(ans)
return render_template('main_page.html', vraag=vraag, ans=ans)
#app.route("/1", methods=["GET", "POST"])
def A1():
test = request.POST
return render_template('check.html', test=test)
main_page.html:
<body>
<p>{{ vraag }}</p>
{% for item in ans%}
<form method="POST" action="{{ url_for('A1') }}">
<input type="submit" name={{ item }} value={{ item }} />
</form>
{% endfor %}
</body>
What am I doing wrong here? As error code it gives 'Unhandled Exception'

request.POST in A1 is not correct. Additionally you should wrap item in quotes.
A1 should look like:
#app.route("/1", methods=["GET", "POST"])
def A1():
if request.method == 'POST':
return render_template('check.html', test=str(request.form))
else:
return "This page doesn't accept GET requests."
request.form is an ImmutableMultiDict object, so you can get exact arguments passed from the form. The above example is only to show you what got passed to the form.

Related

Unable to add list to session in flask

I have simple input field where user is adding note.. and what ever note user is adding it will be displayed above in the list.. and m trying to store in a session in flask
This is my flask code
from flask import Flask, render_template, request, session
from flask_session import Session
app = Flask(__name__)
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
#app.route("/", methods=["GET", "POST"])
def index():
if session.get("notes") is None:
session["notes"]=[]
if request.method == "POST":
note = request.form.get("note")
session["notes"].append(note)
return render_template("session-index.html", notes=session["notes"])
if __name__ == "__main__":
app.run(debug=True)
And this is my html page
{% extends "inherit-layout.html" %}
{% block heading %}
Form Page
{% endblock %}
{% block body %}
<ul>
{% for note in notes %}
<li>{{ note }}</li>
{% endfor %}
</ul>
<form action="{{ url_for('index') }}" method="POST">
<input type="text" name="note" placeholder="Enter Note Here">
<button type="submit">Add Note</button>
</form>
{% endblock %}
What currently happening is when m adding note for second time it is replacing previous one in the list.
from flask import *
app = Flask(__name__)
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
app.config['SECRET_KEY'] = "asddaffffa"
#app.route("/", methods=["GET", "POST"])
def index():
if session.get("notes") is None:
session["notes"]=[]
if request.method == "POST":
note = request.form.get("note")
list = session["notes"]
list.append(note)
session["notes"] = list
return render_template("session-index.html", notes=session["notes"])
if __name__ == "__main__":
app.run(debug=True)
This should work..

Flask view shows 400 error instead of template with form

I'm trying to display a page with a form, then add a Player to the database when the form is submitted. However, I can't view the form because the browser always shows a 400 Bad Request error. Other posts indicate that this could be because the name of the form input doesn't match the key I get from request.form, but all my keys match. Why do I get this error?
<form method="post">
{{ form.hidden_tag() }}
<input name="name">
<input name="available">
<input type="submit">
</form>
#app.route('/addplayer', methods=['GET', 'POST'])
def addplayer():
connect('basketball_contracts', host='localhost', port=27017)
n = request.form['name']
a = request.form['available']
post= Post(
name=n,
available=a
)
post.tags = ['test']
post.save()
return render_template('addplayer.html', form=form)
Your view accepts GET and POST requests. request.form is only filled out on POST. If you try to access a key that doesn't exist, it raises a 400 error. No keys will exist when you GET the page initially.
The common pattern for this is to guard code that requires request.form in an if request.method == 'POST' block. Return a redirect after handling the POST request, otherwise return the rendered template.
from flask import url_for, redirect, render_template
#app.route('/addplayer', methods=['GET', 'POST'])
def addplayer():
if request.method == 'POST':
Post(
name=request.form['name'],
available=request.form['available']
).save()
return redirect(url_for('index'))
return render_template('addplayer.html')
Since you appear to be using Flask-WTF, you can use the form's validate_on_submit method instead of checking method. In that case, you can also access the data through the form instance, and use the form to render the inputs for you.
from flask import url_for, redirect, render_template
#app.route('/addplayer', methods=['GET', 'POST'])
def addplayer():
form = AddPlayerForm()
if form.validate_on_submit():
Post(
name=form.name.data,
available=form.available.data
).save()
return redirect(url_for('index'))
return render_template('addplayer.html', form=form)
<form method=post>
{{ form.hidden_tag() }}
{{ form.name.label}} {{ form.name }}<br>
{{ form.available.label }} {{ form.available }}<br>
<input type=submit value="Add Player">
</form>

Raising an error in WTForm using jinja2

I'm trying to raise an error in Jinja2, in a WTForm, the error should be raised if url input is not validated, but when i submit an invalide url, i get a popup saying "Please enter a url".
how do i pass the default popup and add a custom error message ?
here is the main py:
from datetime import datetime
from flask import Flask, render_template, url_for, request, redirect,flash
from logging import DEBUG
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField
from flask.ext.wtf.html5 import URLField
from wtforms.validators import DataRequired , url
app = Flask(__name__)
app.logger.setLevel(DEBUG)
app.config['SECRET_KEY']='{#\x8d\x90\xbf\x89n\x06%`I\xfa(d\xc2\x0e\xfa\xb7>\x81?\x86\x7f\x1e'
#app.route('/')
#app.route('/index')
def index():
return render_template('base.html')
#app.route('/add', methods=['GET','POST'])
def add():
return render_template('add.html')
# HERE IS THE LOGIN FORM
class Login(FlaskForm):
username = StringField('username')
password = PasswordField('password')
url = URLField('url', validators=[DataRequired(),url()])
#app.route('/form', methods=['GET','POST'])
def form():
form = Login()
if form.validate_on_submit():
url = form.url.data
return redirect(url_for('index'))
return render_template('form.html',form = form )
if __name__ =='__main__':
app.run(debug=True)
and here is the template:
<!DOCTYPE html>
<html>
<head>
<title>form</title>
</head>
<body>
<h1>Hello !</h1>
<form method="POST" action="{{url_for('form')}}">
{{ form.hidden_tag() }}
{{ form.csrf_token }}
{{ form.username.label }}
{{ form.username }}
{{ form.password.label }}
{{ form.password }}
{{ form.url.label }}
{{ form.url }}
{% if form.url.errors %} <p> {{error}}</p> {% endif %}
<button type="submit">Submit</button>
</form>
</body>
</html>
Because you're using the data type URLField, this is rendered as a HTML5 "url" form field type.
Your browser recognises this and performs its own validation on the data submitted:
There is no way for you to override this - it's built in to the browser.
If you need to show a custom error message, you might be able to use a TextField instead, and provide your own URL validation logic.
Add your own message instead of default message in your form defination.
url = URLField('url', validators=[DataRequired(),url(message="Please enter a valid url (e.g.-http://example.com/)")])
As Matt Healy before mentiones, it is the browser that validates URLField.
So if you want a custom error message use StringField (TextField is outdated). If required, a custom message can be used as shown below message='text to display'.
Example:
class XYZForm(FlaskForm):
url = StringField('url', validators=[DataRequired(),url(message='Please enter valid URL')])
description = StringField('description')
Of course the *.html should include code to output an error to the page:
<ul>
{% for error in form.url.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
It seems like novalidate attribute works for your case.

Flask WTF always fails

I'm trying to build a user input form using Flask WTF.
The problem is that when I debug my code, it always fails at
if not form.validate_on_submit():
even if I don't have anything to fail, it just go inside that if statement and my submitted data stays in the form rather than going back to index page.
my server side code
#post_user_blueprint.route('/post_user', methods=['GET', 'POST'])
def post_user():
form = InputForm(request.form)
if not form.validate_on_submit():
return render_template('wtf_input.html', form=form)
return redirect(url_for('.index'))
html (using helper class to macro the input field and error)
<form action="/post_user" method='post' name='post_user' enctype=multipart/form-data >
{% from "_formhelpers.html" import render_field %}
{{ form.csrf }}
{{render_field(form.individual_first_name)}}
{{render_field(form.individual_last_name)}}
<input type='submit' value='SUBMIT'/>
</form>
WTF class
class InputForm(FlaskForm):
individual_first_name = StringField("First Name",
[validators.InputRequired("Please enter first name")])
individual_last_name = StringField("Patient Last Name",
[validators.InputRequired("Please enter last name")])
submit = SubmitField("Send")
Thanks in advance

Determine which WTForms button was pressed in a Flask view

I have a page with multiple links to redirect the user to different pages. I thought using a form would be nicer, so I defined a WTForms Form with multiple SubmitFields. How do I determine which button was clicked and redirect based on that?
class MainForm(Form):
user_stats = SubmitField('User Stats')
room_stats = SubmitField('Room Stats')
#main.route('/')
#login_required
def index():
form = MainForm()
return render_template('index.html', form=form)
<form action="#" method="post">
{{ wtf.quick_form(form) }}
</form>
You added two buttons to the form, so check which of the fields' data is True.
from flask import Flask, render_template, redirect, url_for
from flask_wtf import Form
from wtforms import SubmitField
app = Flask(__name__)
app.secret_key = 'davidism'
class StatsForm(Form):
user_stats = SubmitField()
room_stats = SubmitField()
#app.route('/stats', methods=['GET', 'POST'])
def stats():
form = StatsForm()
if form.validate_on_submit():
if form.user_stats.data:
return redirect(url_for('user_stats'))
elif form.room_stats.data:
return redirect(url_for('room_stats'))
return render_template('stats.html', form=form)
app.run(debug=True)
<form method="post">
{{ form.hidden_tag() }}
{{ form.user_stats }}
{{ form.room_stats }}
</form>

Categories

Resources