23.1. Keeping Track of Data Values¶
In the past two chapters, you created Flask applications to collect user data and display it on a webpage. However, you may have noticed that when you reload the page, any data collected from the form disappears. The same thing happens if you close the page tab, restart the application, or quit the browser completely. Any data assigned to the Python variables is temporary.
This behavior also means we need to be very careful about sending data back and forth between our Python code and a Jinja2 template.
23.1.1. Problem With Guessing a Number¶
Let’s take a look at a function that asks a user to guess a secret number.
Example
The webpage:
The Python code:
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | @app.route('/guess_the_number', methods=['GET', 'POST'])
def guess_the_number():
if request.method == 'POST':
# Collect the user's entry from the web form:
user_guess = int(request.form['user_guess'])
# Check if the user guessed correctly:
if user_guess == magic_number:
message = 'You guessed the number!'
else:
message = 'Nope! Try again.'
else:
magic_number = random.randint(1, 50) # Create a random number from 1 - 50.
message = ''
return render_template('guess_the_number.html', message=message)
|
Line 19 generates a random number and assigns the value to
magic_number
.Line 22 renders the
guess_the_number
template, which displays a form for the user.
Unfortunately, when we run the application and make a guess, the program crashes when we click Go!
Reading the error message tells us what went wrong. In line 14,
magic_number
hasn’t been assigned a value. If we think about the flow of
the program, this might seem odd at first.
The browser sends a
GET
request to theguess_the_number()
function.This triggers the
else
clause on line 18, andmagic_number
is assigned a random number from 1 - 50.Line 22 renders the form in the browser, and the user submits their guess.
The browser sends a
POST
request to the function, and line 11 collects the user’s guess.
Following these steps, it seems like magic_number
should have a value.
However, this is not the case. The return
statement on line 22 renders the
template, but it also ends the guess_the_number()
function. When this
happens, the value we assigned to magic_number
is lost.
When the function runs after the POST
request, Python treats
magic_number
as a brand new variable. The expression
user_guess == magic_number
throws an error because magic_number
has not
been assigned a value yet.
23.1.2. One Solution¶
With a little work, we can modify the guess_the_number()
function to avoid
the error. One way to do this is to send magic_number
to the template, and
then collect it again after the user submits the form. However, this isn’t
ideal.
Assigning a value to magic_number
, sending it to the template, and then
pulling it back into the same function is inefficient. Also, sending
magic_number
to the template makes it part of the HTML page. Even if we
hide it, users who know how to use the browser tools can find the data. If our
goal is to have users guess a secret number, we don’t want to give them the
answer!
23.1.3. A Better Solution¶
For many web applications, we want data to persist. This means saving the
information even if the user refreshes the page, closes the tab, or quits their
browser completely. Persistent data also stays around after a return
statement ends a function.
In this chapter, we will learn two ways to handle short-term data storage. In the following chapters, we will use a database to save information over a longer period of time.