Using Django Sessions

2018-03-23 Thread Derek Zeng
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.

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/a873da51-fe3b-4a75-ba40-7fe6d26fff31%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Using Django Sessions

2018-03-22 Thread Manu Febie
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()