In my second update I will make some improvements to the shopping cart model, notably allowing multiple products to be added to the cart and fixing the remove() method so it actually works.
class Cart(object):
"""
Shopping cart stores products in the session and persists to a database
"""
# Stores the items
__items = dict()
# Constructor
def __init__(self):
# Get cartID from the session if it exists
cartID = session.get('cartID', None)
# If cartID is set then load an instance of the database model
# populated with existing items
if cartID:
cart = CartModel()
self.cartModel = cart.get(cartID)
# If not then create a new instance and save self to the database
# and set cartID in the session
else:
cart = CartModel(object=self, status=0)
DBSession.add(cart)
transaction.commit()
session['cartID'] = cart.id
self.cartModel = cart
# Main methods
def add(self, product, qty):
# Save dictionary of product attributes
items = dict({'id': product.id,
'qty': qty,
'description': product.name,
'price': product.price})
self.set_items(items)
self.save()
def remove(self, productID):
# Remove an item
items = self.get_items()
if int(productID) in items:
del items[int(productID)]
self.save()
def clear(self):
# Clear items from session, but NOT database as we will need
# a record of transactions
session.delete()
def save(self):
# Persist changes
session.save()
self.cartModel.object = self
transaction.commit()
# Getters/Setters
def set_items(self, items):
self.__items[items['id']] = items
session['items'] = self.__items
def get_items(self):
if session.get('items', None):
self.__items = session['items']
return self.__items
All I have done here is change the set_items() method to properly append the items dict to the self.__items dict. The remove method was puzzling to me coming from a background in PHP until I remembered that the keys in a Python dictionary can be any type (except another dictionary) and that the productID passed into it from the controller was a string and the key is an integer. In PHP this would not matter, but Python was throwing a KeyError, but explicitly casting productID to an integer solved this little issue.
Now the cart properly handles adding and removing products from it.
The Controller
I will briefly go over the controller functions in root.py. I think in my finished application I will move all cart related actions into a separate controller but for now when I am mainly just debugging my models I shall leave them in the root controller.
@expose()
def add_to_cart(self, productID, quantity):
# Get cart instance
cart = self.get_cart()
# create a new product object
product = Product()
# add product to cart
cart.add(product.get(productID), quantity)
# Feedback and redirect
flash('Product added')
redirect('/')
@expose()
def remove_from_cart(self, productID):
# Get cart
cart = self.get_cart()
# Remove productID from cart
cart.remove(productID)
# Feedback and redirect
flash('Product removed')
redirect('/')
These are fairly self-explanatory, we simply call the instance of the cart add/remove and then set a flash message and redirect back to the home page.
In my next update I will bring in an address model and start creating some checkout logic so that the cart can do something useful.
No comments:
Post a Comment