简体   繁体   中英

Question about saving form data in flask (flask, Python3)

So, I'm trying to make a budget app, mostly for my own python/flask practice. The app works where the user enters a value in a form, say 'income', and that gets transferred over to the next page.

The form data is saved perfectly when it moves to the next url, but if I try to call it in a later URL, I get a BadRequestKeyError, and the page can't seem to find my form data any longer.

Here's the code:

from flask import Flask, render_template, request, session
from datetime import date
app = Flask(__name__)
app.secret_key = "Nash"

@app.route('/', methods=['GET'])
def entry():
    return render_template('entry.html',
                           the_title='Smith Family Budgeting')

@app.route('/income', methods=['GET'])
def income():
    session['income'] = ''
    return render_template('income.html')

@app.route('/housing', methods=['POST'])
def housing():
    if request.method == 'POST':
        session['housing'] = ''
        session['income'] = request.form["income"]
        return render_template('housing.html', the_income=session['income'])

@app.route('/transportation', methods=['POST'])
def transport():
    if request.method == 'POST':
        income = session["income"]
        session['housing'] = request.form["housing"]
        session['leftover'] = float(income) - float(session['housing'])
        return render_template('trans.html', leftover=session['leftover'])

@app.route('/food', methods=['POST'])
def food():
    if request.method == 'POST':
        session['gas'] = request.form['gas']
        session['leftover'] = int(session['leftover'] - int(session['gas']))
        return render_template('food.html', leftover=session['leftover'])

@app.route('/utilities', methods=['POST'])
def utilities():
    if request.method == 'POST':
        session['food'] = request.form['food']
        session['leftover'] = float(session['leftover']) - float(session['food'])
        return render_template('utilities.html',
                               leftover=session['leftover'])

@app.route('/insurance', methods=['POST'])
def insurance():
    if request.method == 'POST':
        session['bills'] = float(request.form['gas_bill']) + float(request.form['electric_bill']) + float(request.form['internet_bill']) + float(request.form['city_bill'])
        session['leftover'] = float(session['leftover']) - float(session['bills'])
        return render_template('insurance.html', leftover=session['leftover'])

@app.route('/entertainment', methods=['POST'])
def fun():
    if request.method == 'POST':
        session['leftover'] = float(session['leftover']) - float(request.form['insurance']) -float(request.form['life'])
        return render_template('entertainment.html', leftover=session['leftover'])

@app.route('/services', methods=['POST'])
def services():
    if request.method == 'POST':
        session['leftover'] = float(session['leftover']) - float(request.form['derek']) - float(request.form['taylor']) - float(request.form['outings']) - float(request.form['dates'])
        return render_template('services.html', leftover=session['leftover'])

@app.route('/health', methods=['POST'])
def health():
    if request.method == 'POST':
        session['services'] = float(request.form['hulu']) + float(request.form['spotify']) + float(request.form['amc']) + float(request.form['amazon'])
        session['leftover'] = session['leftover'] - session['services']
        return render_template('health.html',
                               leftover=session['leftover'])

@app.route('/savings', methods=['POST'])
def savings():
    if request.method == 'POST':
        session['health'] = float(request.form['health'])
        session['leftover'] = session['leftover'] - session['health']
        return render_template('savings.html',
                               leftover=session['leftover'])

@app.route('/results', methods=['POST'])
def results():
    if request.method == 'POST':
        housing = request.form['housing']
        session['savings_and_givings'] = float(request.form['savings']) - float(request.form['giving'])
        session['leftover'] = session['leftover'] - session['savings_and_givings']
        today = date.today()
        return render_template('results.html',
                               leftover=session['leftover'],
                               date=today,)


app.run(debug = True)

Error Traceback:

Traceback (most recent call last):
File "/python3.7/site-packages/flask/app.py", line 2463, in __call__
return self.wsgi_app(environ, start_response)
File "/python3.7/site-packages/flask/app.py", line 2449, in wsgi_app
response = self.handle_exception(e)
File "/python3.7/site-packages/flask/app.py", line 1866, in handle_exception
reraise(exc_type, exc_value, tb)
File "/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/python3.7/site-packages/flask/app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "/python3.7/site-packages/flask/app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/python3.7/site-packages/flask/app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/python3.7/site-packages/flask/app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "/python3.7/site-packages/flask/app.py", line 1935, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "budget/budget.py", line 84, in results
housing = request.form['housing']
File "/python3.7/site-packages/werkzeug/datastructures.py", line 443, in __getitem__
raise exceptions.BadRequestKeyError(key)
werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser(or proxy) sent a request that this server could not understand.
KeyError: 'housing'

Any ideas for why this might be happening? Thanks in advance

Trying to get a value from a form that doesn't exists in the form. Here housing = request.form['housing']

When storing data in aflask session using session['housing'] = request.form["housing"] the data is stored in the user's browser cookies and will get cleared when the user restarts the browser.

@app.route('/results', methods=['POST'])
def results():
    if request.method == 'POST':
        housing = session['housing']
        session['savings_and_givings'] = float(request.form['savings']) - float(request.form['giving'])
        session['leftover'] = session['leftover'] - session['savings_and_givings']
        today = date.today()
        return render_template('results.html',
                               leftover=session['leftover'],
                               date=today,)

Use get to provide a default value if value doesn't exists

session['income'] = request.form.get("income", 0)

Use session.clear() to clear all the data in user's cookies

@app.route('/', methods=['GET'])
def entry():
        session.clear()
        return render_template('entry.html',
                           the_title='Smith Family Budgeting')

Web pages are stateless, you just can't save their state. If you need to get results of your operations later, consider saving data to some file or use any SQL Database. For small projects and traing I recomend SQLITE3, it is already part of Python standard library and stored as several files (schemas + db itself) with your other projects files (.py, .htmls, .css, etc)

More about what does it mean that web pages are stateless

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM