Джанго не увеличивает количество
В заголовке Django не увеличивает количество товаров, которые уже находятся в корзине. Буду рад любому совету. Почему это происходит и как я могу решить эту проблему.
models.py
class Item(Visits, models.Model):
title = models.CharField(max_length=150)
price = models.IntegerField(default=1000)
image = models.ImageField(upload_to='pictures', default='static/images/man.png')
description = models.TextField(default="Item")
visits = models.IntegerField(default=0)
class OrderItem(models.Model):
order_item = models.ForeignKey(Item, on_delete=CASCADE, null=True)
quantity = models.IntegerField(default=1)
class Cart(models.Model):
order_user = models.OneToOneField(User, on_delete=CASCADE)
order_items = models.ManyToManyField(OrderItem)
ordered = models.BooleanField(default=False)
total = models.IntegerField(default=0, help_text="100 = 1EUR")
views.py
def post(self, request, pk):
if 'buy' in request.POST:
item = get_object_or_404(Item, id=pk)
item_quantity = request.POST.get('quantity')
orderItem, created = OrderItem.objects.get_or_create(order_item=item)
cart, created = Cart.objects.get_or_create(order_user=request.user)
cart.save()
if Cart.objects.filter(order_items=orderItem).exists():
orderItem.quantity += 1
cart.order_items.add(orderItem)
cart.save()
return HttpResponse('Items added to the database')
Такое моделирование выглядит довольно странно. Обычно OrderItem
должен быть моделью перехода [wiki] между Item
и Cart
, так что объект выглядит следующим образом:
class Item(Visits, models.Model):
# ⋮
class OrderItem(models.Model):
item = models.ForeignKey(Item, on_delete=CASCADE, null=True)
cart = models.ForeignKey('Cart', on_delete=CASCADE)
quantity = models.IntegerField(default=1)
class Cart(models.Model):
order_user = models.ForeignKey(User, on_delete=CASCADE)
order_items = models.ManyToManyField(
Item,
related_name='carts',
through=OrderItem
)
ordered = models.BooleanField(default=False)
total = models.IntegerField(default=0, help_text="100 = 1EUR")
Затем мы можем получить текущую активную Cart
или создать ее, если такой Cart
записи нет:
cart, __ = Cart.objects.get_or_create(
user=request.user,
ordered=False
)
и мы можем добавить что-то в эту корзину с помощью:
from django.db.models import F
orderitem, created = OrderItem.objects.get_or_create(
cart=cart,
item_id=pk
)
if not created:
orderitem.quantity = F('quantity') + 1
orderitem.save(force_update=True, update_fields=['quantity'])
Таким образом, вид выглядит следующим образом:
def post(self, request, pk):
if 'buy' in request.POST:
cart, __ = Cart.objects.get_or_create(
user=request.user,
ordered=False
)
orderitem, created = OrderItem.objects.get_or_create(
cart=cart,
item_id=pk
)
if not created:
orderitem.quantity = F('quantity') + 1
orderitem.save(force_update=True, update_fields=['quantity'])
return redirect('name-of-some-view')
или если количество может быть увеличено с помощью параметра:
def post(self, request, pk):
if 'buy' in request.POST:
cart, __ = Cart.objects.get_or_create(
user=request.user,
ordered=False
)
quantity = request.POST.get('quantity')
orderitem, created = OrderItem.objects.get_or_create(
cart=cart,
item_id=pk,
defaults={'quantity': quantity}
)
if not created:
orderitem.quantity = F('quantity') + quantity
orderitem.save(force_update=True, update_fields=['quantity'])
return redirect('name-of-some-view')
Примечание: В случае успешного POST запроса, вы должны сделать
redirect
. [Django-doc] для реализации паттерна Post/Redirect/Get [wiki]. Это позволяет избежать повторения POST-запроса, когда пользователь обновляет браузер. браузер.