Reputation: 115
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:
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.
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))
Upvotes: 0
Views: 5283
Reputation: 4689
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.
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:
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)
# 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)
Upvotes: 1