Flask return redirect(url_for) error for missing parameter
Flask return redirect(url_for) error for missing parameter
I have the following code and when I try a return redirect(url_for)
on the present
and future
functions I get the following error message:
return redirect(url_for)
present
future
TypeError: home() missing 1 required positional argument: 'calc_type'
I've tried multiple ways to pass the calc_type
variable to the home
function and always get the same error. Any help is appreciated.
calc_type
home
from flask import render_template, redirect, url_for, request
from app import app, db
from models import Pres, Future
@app.route('/home')
def home(calc_type):
if (calc_type == "present"):
try:
inputs = Pres.query.all()
for item in inputs:
cash = item.cash
rate = item.rate
periods = item.periods
pv = cash / (1 + rate)**periods
return render_template('present.html', inputs=inputs, cash=cash, pv=pv)
except:
return render_template('present.html')
elif (calc_type == "future"):
inputs = Future.query.all()
for item in inputs:
cash = item.cash
rate = item.rate
periods = item.periods
fv = cash * (1 + rate)**periods
return render_template('present.html', inputs=inputs, cash=cash, fv=fv)
@app.route('/present', methods=['GET', 'POST'])
def present():
input = Pres(request.form['cash'], request.form['rate'], request.form['periods'])
calc_type = "present"
db.session.add(input)
db.session.commit()
return redirect(url_for('home', calc_type=calc_type))
@app.route('/future', methods=['GET', 'POST'])
def future():
input = Future(request.form['cash'], request.form['rate'], request.form['periods'])
calc_type = "future"
db.session.add(input)
db.session.commit()
return redirect(url_for('home', calc_type=calc_type))
calc_value
/home
ur_for()
I expect it to be a string of either "present" or "future" that will then be used in the "if (calc_type = "present)" condition in the 'home' function. My html has a dropdown where the user can select either a present value or a future value calculation. That's all working fine. I just can't get the parameter to pass. Or the 'home' function to accept it.
– jpanknin
13 hours ago
1 Answer
1
The way you have your home()
view, there is no way for it to receive a parameter from url_to
because there is no such a variable in the route's path.
home()
url_to
View functions are wrapped by flask and will behave differently than regular functions.
For the home view to receive the variable you would have to define it with a variable in it's route path:
@app.route('/home/<string:calc_type>')
def home(calc_type):
...
# Result:
>>> url_for('route', calc_type='present')
'/home/present'
Alternatively, you can pass it as url query variables:
@app.route('/home')
def home():
calc_type = request.args.get('calc_type')
# Result:
>>> url_for('route', calc_type='present')
'/home?calc_type=present'
But most importantly, you should also try to separate view/routing logic from other code and keep your views as light as possible.
Here are two ways you could solve this:
Option 1
PS: I would not do it this way, but is the closest to your code as is.
def get_view(calc_type):
if (calc_type == "present"):
try:
inputs = Pres.query.all()
for item in inputs:
cash = item.cash
rate = item.rate
periods = item.periods
pv = cash / (1 + rate)**periods
return render_template('present.html', inputs=inputs, cash=cash, pv=pv)
except:
return render_template('present.html')
elif (calc_type == "future"):
inputs = Future.query.all()
for item in inputs:
cash = item.cash
rate = item.rate
periods = item.periods
fv = cash * (1 + rate)**periods
return render_template('present.html', inputs=inputs, cash=cash, fv=fv)
@app.route('/present', methods=['GET', 'POST'])
def present():
input = Pres(request.form['cash'], request.form['rate'], request.form['periods'])
calc_type = "present"
db.session.add(input)
db.session.commit()
return get_view(calc_type)
@app.route('/future', methods=['GET', 'POST'])
def future():
input = Future(request.form['cash'], request.form['rate'], request.form['periods'])
calc_type = "future"
db.session.add(input)
db.session.commit()
return get_view(calc_type)
Option 2
# calculations.py
from models import Pres, Future
def present_calc():
try:
inputs = Pres.query.all()
for item in inputs:
cash = item.cash
rate = item.rate
periods = item.periods
pv = cash / (1 + rate)**periods
return dict(inputs=inputs, cash=cash, pv=pv)
except:
return dict()
def future_calc():
inputs = Future.query.all()
for item in inputs:
cash = item.cash
rate = item.rate
periods = item.periods
fv = cash * (1 + rate)**periods
return dict(inputs=inputs, cash=cash, fv=fv)
# views.py
from flask import render_template, redirect, url_for, request
from app import app, db
from .calculations import present_calc, future_calc
from app import db
@app.route('/present', methods=['GET', 'POST'])
def present():
inputs = Pres(
cash=request.form['cash'],
rate=request.form['rate'],
periods=request.form['rate'])
db.session.add(inputs)
db.session.commit()
calcs = present_calc()
return render_template('present.html', **calcs)
@app.route('/future', methods=['GET', 'POST'])
def future():
inputs = Pres(
cash=request.form['cash'],
rate=request.form['rate'],
periods=request.form['rate'])
db.session.add(inputs)
db.session.commit()
calcs = future_calc()
return render_template('future.html', **calcs)
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
What are you expecting
calc_value
to be when you access/home
? It should probably be either be a query param, or be part of or url You can pass a value usingur_for()
when the value is part of the url: @app.route('/home/<string:calc_type>'): def home(calc_type):– gtalarico
13 hours ago