Using Django Sessions

120 views
Skip to first unread message

Manu Febie

unread,
Mar 22, 2018, 9:09:55 PM3/22/18
to Django users
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()
       return render(request, 'orders/order_success.html', {'cart': cart})
   
   return render(request, 'cart/cart_detail.html', {'cart': cart})

I hope my question is clear and someone can help me with this.

Derek Zeng

unread,
Mar 23, 2018, 9:40:15 AM3/23/18
to Django users
You can have a flag in cart class to mark if things are cleared. Then in the __iter__ function, check the flag before getting the keys.

If you do this you also need to add the check in add/remove and others accordingly.

Reply all
Reply to author
Forward
0 new messages