Reputation: 1817
I am trying to delete an item from the cart
and I have some issues to do it. Here is the function:
def cart_contents(request):
"""
Ensures that the cart contents are available when rendering
every page
"""
cart = request.session.get('cart', {})
cart_items = []
total = 0
destination_count = 0
for id, quantity in cart.items():
destination = get_object_or_404(Destinations, pk=id)
#remove = request.session.pop('cart', {id}) <<<<<<
price = destination.price
total += quantity * destination.price
destination_count += quantity
cart_items.append({'id': id, 'quantity': quantity, 'destination': destination, 'price':price, 'remove':remove})
#cart_item will loop into the cart.
return {'cart_items': cart_items, 'total': total, 'destination_count': destination_count}
Template.html
{% for item in cart_items %}
{{ item.remove }}
{% endfor %}
I've added a remove variable remove = request.session.pop('cart', {id})
but if I use it in the code it will first not allow me to add more than one item and when I click the trash-can-button to remove the item it deletes all the cart
in the session.
The following image has two items in the card based by its id and the quantity as {'id', quantity} = {'2': 1, '3': 2}
.
Upvotes: 0
Views: 1385
Reputation: 1817
I've found the answer. I made cart
and quantity
correlate each other. So, if you have three items in the cart you can delete/decrement until it reach 0 in the cart and if so, the cart will redirect to the destinations url.
def adjust_cart(request, id):
"""
Adjust the quantity of the specified product to the specified
amount
url for this function should be <str:id> not <int:id>
- otherwise you need to add str() method for each dict representation.
"""
cart = request.session.get('cart', {})
quantity = cart[id] - 1 #decreases the cart quantity until deletes from cart
if quantity > 0:
cart[id] = quantity
else:
cart.pop(id)
request.session['cart'] = cart
if not cart: #if all products be deleted from cart return to destination page
return redirect(reverse('destination'))
return redirect(reverse('view_cart'))
cart.html
{% for item in cart_items %}
</tr>
...
<td class="border-0 align-middle"><a href="{% url 'adjust_cart' item.id%}" class="text-dark"><i class="fa fa-trash"></i></a></td>
</tr>
{% endfor %}
url.py
from django.urls import path
from . import views
urlpatterns = [
...
...
path('adjust/<str:id>/', views.adjust_cart, name="adjust_cart"),
]
Remembering that cart_items
is a list with appended dictionary. Please if any acronym is wrong you can correct me.
Upvotes: 0
Reputation: 1531
request.session.pop('cart')
will remove the cart in the session. Assuming that when you click the delete icon, you pass the id of the cart item, you can get the cart from the session and delete the necessary id and set the session again with the new cart value:
cart = request.session.get("cart", {})
id_to_be_removed = request.POST["id_to_be_removed"]
# do other things here or anywhere else
if id_to_be_removed in cart:
del cart[id_to_be_removed] # remove the id
request.session["cart"] = cart
# return
Upvotes: 2