Hello,
I am practicing for my college exams. I am building a Restaurant Order
System with Django and I am using Django sessions for the first. I borrowed
some ideas from the "Django by example".
Below you can find the MenuItem model and Order Model.
class MenuItem(models.Model):
category = models.ForeignKey(Category, related_name='menu_items')
# table ???
name = models.CharField(max_length=255, db_index=True)
slug = models.SlugField(max_length=255, db_index=True, default='')
description = models.TextField(blank=True)
image = models.ImageField(upload_to='menu_items/%Y/%m/%d', blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
available = models.BooleanField(default=True)
added_on = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Order(models.Model):
STATUS_CHOICES = (
('in behandeling', 'In behandeling'),
('klaar', 'Klaar')
)
# random_id = models.CharField(max_length=255)
table = models.ForeignKey(settings.AUTH_USER_MODEL)
item = models.ForeignKey(MenuItem, related_name='order_items')
price = models.DecimalField(max_digits=10, decimal_places=2)
quantity = models.PositiveIntegerField(default=1)
status = models.CharField(max_length=50, choices=STATUS_CHOICES, default='in
behandeling')
paid = models.BooleanField(default=False)
timestamp = models.DateTimeField(auto_now_add=True)
Below you can find a Cart class which handles adding, removing, iterating
etc. over the Menu Items using Django sessions. What I need is a function
in this class that only clears the items I have in the cart, but I still
need the total price. Right now I have the "clear" function which removes
the entire cart from the session. But since I am kinda confused on how to
do this I need some help.
from decimal import Decimal
from django.conf import settings
from menu.models import MenuItem
class Cart:
def __init__(self, request):
self.session = request.session
cart = self.session.get(settings.CART_SESSION_ID)
if not cart:
cart = self.session[settings.CART_SESSION_ID] = {}
self.cart = cart
def add(self, menu_item, quantity=1, update_quantity=False):
# Add a menu item to the cart or update its quantity
menu_item_id = str(menu_item.id)
if menu_item_id not in self.cart:
self.cart[menu_item_id] = {'quantity': 0,
'price': str(menu_item.price)}
if update_quantity:
self.cart[menu_item_id]['quantity'] = quantity
else:
self.cart[menu_item_id]['quantity'] += quantity
self.save()
def save(self):
# Update the session cart
self.session[settings.CART_SESSION_ID] = self.cart
# Mark the session as "modified" to make sure its saved
self.session.modified = True
def remove(self, menu_item):
# Remove a product from the cart
menu_item_id = str(menu_item.id)
if menu_item_id in self.cart:
del self.cart[menu_item_id]
self.save()
def __iter__(self):
# Iterate over the item in the cart and get the products from the DB
menu_item_ids = self.cart.keys()
# get thte product objects and add them to the cart
menu_items = MenuItem.objects.filter(id__in=menu_item_ids)
for menu_item in menu_items:
self.cart[str(menu_item.id)]['menu_item'] = menu_item
for item in self.cart.values():
item['price'] = Decimal(item['price'])
item['total_price'] = item['price'] * item['quantity']
yield item
def __len__(self):
# Count all the items in the cart
return sum(item['quantity'] for item in self.cart.values())
def get_total_price(self):
return sum(Decimal(item['price']) * item['quantity'] for item in self
.cart.values())
def clear(self):
# Remove cart from the session
del self.session[settings.CART_SESSION_ID]
self.session.modified = True
And below here you'll find the view that handles saving the items in the
request cart in to the Order model. Instead of calling the cart.clear()
function I need to call a function that removes the ordered items from the
cart while still having the total price in this session.
@login_required
def create_order(request):
cart = Cart(request)
if request.method == 'POST':
for item in cart:
Order.objects.create(table=request.user,
item=item['menu_item'],
price=item['price'],
quantity=item['quantity'])
cart.clear()