Flask return redirect(url_for) error for missing parameter

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP

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))





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 using ur_for() when the value is part of the url: @app.route('/home/<string:calc_type>'): def home(calc_type):
– gtalarico
13 hours ago



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.

Comments

Popular posts from this blog

Executable numpy error

PySpark count values by condition

Trying to Print Gridster Items to PDF without overlapping contents