Optional keyword argument in render_template - python

Here is my code:
#app.route('/', methods=['GET', 'POST'])
def index():
form = CryptoForm()
if session.get('currency'):
currency = session.get('currency')
price1 = Get_info(currency)
price = price1.get_filtered_data()
if form.validate_on_submit():
flash('success', 'success')
currency = form.crypto.data
get_price = Get_info(currency)
session['currency'] = get_price.get_filtered_data()
return redirect(url_for('index'))
return render_template("index.html", form=form, price=price)
What I'm trying to do is to get the user to type a crypto acronym into the form and submit it. When the user submits it, it should display the price. But when the page loads for first time there is no price so the price=price in render_template is giving me error. How could I fix it so there is a price only if he submit the form?

If you want to do different things whether the form is submitted or not, check what the method is.
from flask import request
#app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
# The user submitted something.
else:
# The user fetched something.

Related

How can I clear values from WTF form upon submission? [duplicate]

I want to reset the form after it validates. Currently the form will still show the previous data after it is submitted and valid. Basically, I want the form to go back to the original state with all fields clean. What is the correct to do this?
#mod.route('/', methods=['GET', 'POST'])
def home():
form = NewRegistration()
if form.validate_on_submit():
#save in db
flash(gettext(u'Thanks for the registration.'))
return render_template("users/registration.html", form=form)
The issue is that you're always rendering the form with whatever data was passed in, even if that data validated and was handled. In addition, the browser stores the state of the last request, so if you refresh the page at this point the browser will re-submit the form.
After handling a successful form request, redirect to the page to get a fresh state.
#app.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
# do stuff with valid form
# then redirect to "end" the form
return redirect(url_for('register'))
# initial get or form didn't validate
return render_template('register.html', form=form)
davidism answer is correct.
But once I had to reload a form with only a few fields that had to be resetted.
So, I did this, maybe it's not the cleanest way but it worked for me:
form = MyForm()
if form.validate_on_submit():
# save all my data...
myvar1 = form.field1.data
myvar2 = form.field2.data
# etc...
# at first GET and at every reload, this is what gets executed:
form.field1.data = "" # this is the field that must be empty at reload
form.field2.data = someobject # this is a field that must be filled with some value that I know
return render_template('mypage.html', form=form)
You can clear a form by passing formdata=None
#mod.route('/', methods=['GET', 'POST'])
def home():
form = NewRegistration()
if form.validate_on_submit():
#save in db
######### Recreate form with no data #######
form = NewRegistration(formdata=None)
flash(gettext(u'Thanks for the registration.'))
return render_template("users/registration.html", form=form)
you can also return new form object using render_template if form does not validates you can also pass message
#mod.route('/', methods=['GET', 'POST'])
def home():
form = NewRegistration()
if form.validate_on_submit():
#save in db
return render_template("user/registration.html", form = NewRegistration())
return render_template("users/registration.html", form=form)

How to give arguments to view with flask, redirect url_for

I have an application build with flask and I want to pass one input tag from my current html view ('/setpickup') to another view, in order to reuse the variable values of that input and print them again in the new view ('/payments.html'). But I dont know if it is possible, thanks you. Here is a brief of the code that is not working at this moment.
#app.route('/')
#app.route('/setpickup', methods=['GET', 'POST'])
#login_required
def setpickup():
form = RideForm()
device = Utils.getDevice()
if request.method == 'POST':
data_input_data = form.data_input.data
return redirect(url_for('payment', data_input_data=data_input_data))
#app.route('/payment')
#login_required
def payment(data_input_data):
device = Utils.getDevice()
return render_template("/"+device+"/payment.html",
device=device,
data_input_data=data_input_data)

Python/Flask. How can include multiple forms on a single view.py file

I am developing a python web application using the Flask framework. The application has several forms namely: The login form, the registration form, check balance form, withdraw cash form, and transfer money form. I have a single view.py file that i intend to use to render all these forms like this:
###login form
#app.route('/login', methods = ['POST'])
def login():
form = LoginForm()
if request.method == 'POST':
if form.validate() == False:
flash('pin is required.')
else:
return render_template('index.html')
elif request.method == 'GET':
return render_template('login.html', form = form)
##withdraw cash
#app.route('/withdrawCash', methods=['GET', 'POST'])
def withdrawCash():
form = withdrawCashForm()
if request.method == 'POST':...
##transfer cash
#app.route('/transferCash', methods=['GET', 'POST'])
def transferCash():
form = transferCashForm()
if request.method == 'POST':......etc
Is this possible to have one view file rendering all these forms or should i have view files for each form?
The question above has been edited. I initially thought i had gone around the problem but after reviewing the problem it is clear that whatever answer i had provided was wrong.

Redirect to other view after submitting form

I have a survey form. After submitting the form, I'd like to handle saving the data then redirect to a "success" view. I'm using the following code right now, but it just stays on the current url, while I'd like to go to /success. How can I do this?
#app.route('/surveytest', methods=['GET', 'POST'])
def surveytest():
if request.method == 'GET':
return render_template('test.html', title='Survey Test', year=datetime.now().year, message='This is the survey page.')
elif request.method == 'POST':
name = request.form['name']
address = request.form['address']
phone = request.form['phone']
email = request.form['email']
company = request.form['company']
return render_template('success.html', name=name, address=address, phone = phone, email = email, company = company)
You have the right goal: it's good to redirect after handling form data. Rather than returning render_template again, use redirect instead.
from flask import redirect, url_for, survey_id
#app.route('/success/<int:result_id>')
def success(result_id):
# replace this with a query from whatever database you're using
result = get_result_from_database(result_id)
# access the result in the tempalte, for example {{ result.name }}
return render_template('success.html', result=result)
#app.route('/survey', methods=["GET", "POST"])
def survey():
if request.method == 'POST':
# replace this with an insert into whatever database you're using
result = store_result_in_database(request.args)
return redirect(url_for('success', result_id=result.id))
# don't need to test request.method == 'GET'
return render_template('survey.html')
The redirect will be handled by the user's browser, and the new page at the new url will be loaded, rather than rendering a different template at the same url.
Though I am not specifically answering your current question I found myself with a similar problem with getting the page to redirect after the submission button had been clicked. So I hope this solution could potentially work for others that find themselevs in a similar predicament.
This example uses Flask forms for handling forms and submissions.
from flast_wtf import FlaskForm
#app.route("/", methods=["GET", "POST"])
def home():
stock_form = StockForm()
tick = stock_form.text_field.data
if tick != None:
return redirect(f'/{tick}', code=302)
return render_template("home.html", template_form=stock_form, ticker=tick)
The if statement checks that the submission after being clicked has a value, then redirects to your chosen link. This code is a copy and paste from a badly programmed stock price lookup.

Flask - Pass Variables From Redirect to render_template

I have a question regarding redirecting to a function that renders a template. I have two functions:
#user.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'GET':
return render_template('register.html')
email = request.form['email']
if User.query.filter(User.email == email).first() is not None:
flash('Account already exists for this email address!')
return redirect(url_for('user.login'))
and
#user.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
return "Hello"
In the first function, with the line return redirect(url_for('user.login')), I want to pass the email variable with that redirect, so I can have render_template in the second function display that variable on an HTML page. I tried the following:
return redirect(url_for('user.login', defaultEmail=email))
in the first function and
return render_template('login.html', defaultEmail=email))
but it gives me NameError: global name 'email' is not defined. How would I go about doing this?
The url_for should pass email through the query string. It can by accessed by login as part of request.args.
email = request.args.get('defaultEmail')

Categories