Я учусь Django, так что, возможно, это не лучший способ сделать то, что я хочу.
То, что я пытаюсь сделать здесь, это отобразить элемент, который был выбран несколько раз в корзина, только один раз (и количество раз, когда она была выбрана рядом с ней)
Я целый день пытался найти способ, но самое близкое, что мне удалось сделать, это внутри представлений произвести два набора: single_items и множественные_items.
У меня нет проблем с отображением элемента, который был выбран только один раз, но когда дело доходит до элементов, выбранных несколько раз, я могу отображать их только n раз с количеством появлений в следующем к нему, как показано на рисунке
Хотя я бы предпочел сделать все вычисления с кодом python (в views.py) решение с Django мне подойдет язык шаблонов.
Пожалуйста, примите во внимание, что мне нужно передать идентификатор элемента в URL, чтобы заставить работать ссылку на удаление.
вот виды. py
from django.shortcuts import render, redirect
from .models import Cart, Item, CartItem
from django.db.models import Sum
# Create your views here.
def home(request):
items = Item.objects.all()
carts = Cart.objects.all()
length = len(Cart.objects.all())
cart = carts[length - 1]
cart_items = cart.items.all()
total = cart_items.aggregate(Sum('price'))['price__sum']
if total is None:
total = 0
number_of_items = cart_items.count()
deletable_items = CartItem.objects.all()
occurrences = None
single_items = set()
multiple_items = set()
for deletable_item in deletable_items:
occurrences = deletable_items.filter(item__name=deletable_item.item).count()
if occurrences > 1:
deletable_item.occurrences = occurrences
multiple_items.add(deletable_item)
elif occurrences == 1:
deletable_item.occurrences = occurrences
single_items.add(deletable_item)
return render(request, 'cart/home.html', {'cart': cart,
'items': items,
'cart_items': cart_items,
'total': total,
'number_of_items': number_of_items,
'deletable_items': deletable_items,
'multiple_items': multiple_items,
'single_items': single_items,
'occurrences': occurrences
})
def add_to_cart(request, item_id):
item_id = Item.objects.get(id=item_id)
carts = Cart.objects.all()
length = len(Cart.objects.all())
cart = carts[length - 1]
cart_item = CartItem.objects.create(item=item_id, cart=cart)
return redirect(home)
def remove_from_cart(request, item_id):
item_to_remove = CartItem.objects.get(id=item_id)
item_to_remove.delete(
)
return redirect(home)
* 102 0 * и мой шаблон
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Home page</title>
</head>
<body>
<h1>My Restaurant</h1>
<div><h1>Menu</h1></div>
{% for item in items %}
<ul>{{ item }} £{{ item.price}} <a href="{% url 'add_to_cart' item.id %}">Add</a></ul>
{% endfor %}
<div><h1>Order</h1></div>
{{ cart }}
<br>
<h2>items selected: {{ number_of_items }}</h2>
{% for single_item in single_items %}
<ul>{{ single_item }} x {{ single_item.occurrences }} <a href="{% url 'remove_from_cart' single_item.id %}">Remove</a></ul>
{% endfor %}
{% for multiple_item in multiple_items %}
<ul>{{ multiple_item }} x {{ multiple_item.occurrences }} <a href="{% url 'remove_from_cart' multiple_item.id %}">Remove</a></ul>
{% endfor %}
<h2>Total</h2>
{{ total|floatformat:2 }}
</body>
</html>
и на всякий случай модели
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Item(models.Model):
name = models.CharField(max_length=25)
price = models.DecimalField(max_digits=5, decimal_places=2)
def __str__(self):
return self.name
class Cart(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
items = models.ManyToManyField(Item, through='CartItem')
def __str__(self):
return 'Order number: %s' % self.id
class CartItem(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
cart = models.ForeignKey(Cart, on_delete=models.CASCADE)
def __str__(self):
return str(self.item)
РЕДАКТИРОВАТЬ
на данный момент я использую этот view.py, который был предложен Виллем Ван Онсем
from django.shortcuts import render, redirect
from .models import Cart, Item, CartItem
from django.db.models import Sum, Count, F
# Create your views here.
def home(request):
cart = Cart.objects.filter(user=request.user).last()
items = Item.objects.all()
cart_items = Item.objects.filter(
cartitem__cart=cart
).annotate(
ncount=Count('cartitem')
)
total = cart_items.aggregate(total=Sum(F('price') * F(float('ncount'))))['total']
context = {
'items': items,
'total': total,
'cart_items': cart_items
}
return render(request, 'cart/home.html', context)
def add_to_cart(request, item_id):
item_id = Item.objects.get(id=item_id)
carts = Cart.objects.all()
length = len(Cart.objects.all())
cart = carts[length - 1]
cart_item = CartItem.objects.create(item=item_id, cart=cart)
return redirect(home)
def remove_from_cart(request, item_id):
item_to_remove = CartItem.objects.get(id=item_id)
item_to_remove.delete()
return redirect(home)