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