создаю для интернет магазина корзину и встал выбор в том, каким образом эту корзину реализовывать. Мне нужно не просто прикрутить, чтобы работало, а именно правильно, потому что хочу сделать проект себе в резюме.
1 способ - это использование баз данных, но в данном подходе используют receiver, я очень много слышал, что это дурной тон и их(receiver'ы) лучше вообще никогда не использовать.
class Product(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=64, unique=True)
description = models.TextField(default='')
cost = models.DecimalField(default=0.00, max_digits=10, decimal_places=2)
class Cart(models.Model):
user = models.ForeignKey(User, null=True, blank=True, on_delete='CASCADE')
count = models.PositiveIntegerField(default=0)
total = models.DecimalField(default=0.00, max_digits=10, decimal_places=2)
updated = models.DateTimeField(auto_now=True)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return "User: {} has {} items in their cart. Their total is ${}".format(self.user, self.count, self.total)
class Entry(models.Model):
product = models.ForeignKey(Product, null=True, on_delete='CASCADE')
cart = models.ForeignKey(Cart, null=True, on_delete='CASCADE')
quantity = models.PositiveIntegerField()
def __str__(self):
return "This entry contains {} {}(s).".format(self.quantity, self.product.name)
@receiver(post_save, sender=Entry)
def update_cart(sender, instance, **kwargs):
line_cost = instance.quantity * instance.product.cost
instance.cart.total += line_cost
instance.cart.count += instance.quantity
instance.cart.updated = datetime.now()
2 способ это использование django-sessions хранение информации о товарах пользователя в сессиях, минус такого подхода заключается в том, что сессии живут 2 недели, и после корзина будет пуста, что не очень желательно также.
from decimal import Decimal
from django.conf import settings
from shop.models import Product
class Cart(object):
def __init__(self, request):
"""
Инициализируем корзину
"""
self.session = request.session
cart = self.session.get(settings.CART_SESSION_ID)
if not cart:
# save an empty cart in the session
cart = self.session[settings.CART_SESSION_ID] = {}
self.cart = cart
def add(self, product, quantity=1, update_quantity=False):
"""
Добавить продукт в корзину или обновить его количество.
"""
product_id = str(product.id)
if product_id not in self.cart:
self.cart[product_id] = {'quantity': 0,
'price': str(product.price)}
if update_quantity:
self.cart[product_id]['quantity'] = quantity
else:
self.cart[product_id]['quantity'] += quantity
self.save()
def save(self):
# Обновление сессии cart
self.session[settings.CART_SESSION_ID] = self.cart
# Отметить сеанс как "измененный", чтобы убедиться, что он сохранен
self.session.modified = True