
Shopping Cart Exercise
Shopping Carts in Flask¶
We will do an exercise in which we will build a working "shopping cart" app in Flask.
- I'll give you starting code in a directory that you can copy using cp or curl.
- I'll demo the initial version and the working version.
- You will implement the working version.
If you want to play with a working example of a cart
Here's a video TBD of the demo of the before and after version. The steps:
- run the start version
- buy a soda; this succeeds. Note the cart contents and the flashed message
- buy a beer. this also succeeds. It shouldn't.
- buy a glass of wine.
- try refreshing the page; note that because the form is POSTed, we get the warning
- "hide cart" button is not yet implemented
- "clear cart" button is not yet implemented
- the "I am 21" button is not yet implemented
Shopping Cart Code¶
Unlike the demo in the reading, for the shopping cart code I used POST for almost all form submissions, since they all change the state of the app, and I used the POST-REDIRECT-GET pattern, using flashing for messages. The one exception is ordering drinks.
This has the effect of breaking up the code over several routes, so I'll discuss these each in turn. Fortunately, the code for each is fairly short.
Shopping route
This route renders the page that allows customers to order items:
@app.route('/session/cart', methods=['GET','POST'])
def session_cart():
# use these defaults if cart isn't in session
cart = session.get('cart', {'beer':0, 'wine':0, 'soda':0})
## TODO: determine from the session whether to show the cart
## Also, whether the customer is of age
show = True
print('show: {}'.format(show))
print('cart: {}'.format(cart))
if request.method == 'POST':
# ordering something
## TODO: determine whether the person is of age and can order this
## item. Refuse if not
item = request.form.get('itemid')
cart[item] += 1
flash('Thank you for buying a glass of '+item)
session['cart'] = cart # store the updated cart
return render_template('cart-template.html',
title='Beverage Orders',
cartContents=show,
cart=cart)
The session stores the shopping cart as a Python dictionary. The
default value is the second argument of the .get
method, so this
will initialize the cart if the session doesn't have one. Remember
that we always have to determine what to do if the session is missing,
since it comes from the user and could disappear at any time.
In the exercise, you will get from the session the stored value of whether to show the cart or not. You'll also determine whether the customer is of age, which is also stored in the session.
The route also handles ordering a drink, where the itemid is in the form, and it's just stored in the cart.
In the exercise, you'll have to determine whether the customer can order this drink, depending on whether they are of age.
Showing and Hiding the Cart
There are two related routes, one for when the user wants to hide the cart and one for when the user wants to show the cart. Remember that that's a sticky setting: The cart will be shown or hidden every time, until the user changes the mode.
@app.route('/show_cart/', methods=['POST'])
def show_cart():
session['show_cart'] = True
return redirect(url_for('session_cart'))
@app.route('/hide_cart/', methods=['POST'])
def hide_cart():
## to do; don't show cart
flash('not yet implemented')
return redirect(url_for('session_cart'))
In the exercise, you'll implement the code to switch to hidden carts.
Setting that the User is Of Age
The session will also store whether the user is of age (21+). We'll assume that someone checks the customer's ID card and verifies and makes the setting. Again, this is a sticky setting: the customer doesn't have to keep verifying their age with each purchase.
@app.route('/iam21/', methods=['POST'])
def iam21():
flash('not yet implemented')
return redirect(url_for('session_cart'))
In the exercise, you'll have to implement this.
Clearing the Cart
Finally, the customer should be able to clear the cart (or maybe the server does it when all the drinks have been delivered). Here's the code:
@app.route('/clearCart', methods=['POST'])
def clearCart():
## to do; clear the cart
flash('not yet implemented')
return redirect(url_for('session_cart'))
Again, you'll have to implement that.
Exercise¶
The shopping cart example has several non-working buttons. One is "I am 21"; if the user has pressed that button, they should be allowed to order beer and wine, otherwise, they have to stick to soft drinks. The app should remember that behavior over the course of the session.
Implement that behavior.
Also implement the buttons to hide/show the cart and to clear the cart.
Here's a video TBD of the finished app.
Copying the App
cp -r ~cs304/pub/downloads/session_cart session_cart
Then:
- Work with the
start.py
example. Run it and test it. - You'll need to implement a way to set the "I am 21" value
- You'll need to read the "I am 21" value (true/false) out of the session, including appropriate defaults
- You'll need to modify the ordering part of the logic to respond to the "I am 21" value
Note that we don't (yet) have a way to reset the contents of the session. You can use the Chrome inspector to just delete the cookie. You can also implement the "clear cart" button, which should also reset the "I am 21" value.
My solution is available in done.py
. We can use "diff" to compare
start.py
and done.py
.