Issue
So, I am a begginer coding an e-commerce project on Django. I've managed to add a "delete item"function to remove items from the cart. However, when the item is removed, the order isn't. OrderItem and Order are 2 sepparate models, I'd like so that when an OrderItem i fully deleted and the cart is empty, for the order itself to be deleted too. I'll attach de code for the models and the functios.
Order model:
class Order(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, null=True, blank=True)
date_ordered = models.DateTimeField(auto_now_add=True)
complete = models.BooleanField(default=False)
transaction_id = models.CharField(max_length=100, null=True)
def __str__(self):
return str(self.id)
@property
def get_cart_total(self):
orderitems = self.orderitem_set.all()
total = sum([item.get_total for item in orderitems])
return total
@property
def get_cart_items(self):
orderitems = self.orderitem_set.all()
total = sum([item.quantity for item in orderitems])
return total
OrderItem model:
class OrderItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True)
quantity = models.IntegerField(default=0, null=True, blank=True)
date_added = models.DateTimeField(auto_now_add=True)
@property
def get_total(self):
total = self.product.price * self.quantity
return total
The function for deleting the items:
def eliminaritem(request, id):
if request.method == "POST":
item = OrderItem.objects.get(product = id)
item.delete()
return render(request, "store/deletecartitem.html", {'item': item})
if OrderItem.objects.all == None:
customer = request.user.customer
order = Order.objects.all(customer = customer)
order.delete()
The first part of this functions works, however the way I approached the second IF is horrible. So basically when there aren't any OrderItems, the Order should be deleted. Whenever an item is added to cart, the Order is created
This is the logic behind the cart function :
def cart(request):
if request.user.is_authenticated:
customer = request.user.customer
order, created = Order.objects.get_or_create(customer = customer, complete = False)
items = order.orderitem_set.all()
else:
items = []
order = {'get_cart_total':0, 'get_cart_items':0}
context = {'items': items, 'order': order}
return render(request, 'store/cart.html', context)
This is the logic in the template:
{% if order != None %}
then it shows the items which were added else: No items are in the cart
So when an item is added to the cart, and then it is deleted, leaving the cart empty, the page still won't say No items are in the cart, that is the prohblem.
I dont really care about the order being deleted if the page shows no items in cart when it is empty
Solution
I assume you are using the eliminaritem()
view to delete the item.
def eliminaritem(request, id):
if request.method == "POST":
item = OrderItem.objects.get(product = id)
item.delete()
return render(request, "store/deletecartitem.html", {'item': item})
if OrderItem.objects.all == None:
customer = request.user.customer
order = Order.objects.all(customer = customer)
order.delete()
The problem here is that OrderItem.objects.all()
would return all OrderItems of all Orders. As long as there is somewhere a cart with an item the quer will never be empty. Also since you return before the second if can be executed the code will never be reached.
def eliminaritem(request, id):
if request.method == "POST":
item = OrderItem.objects.get(product = id)
# First get the order behind the item.
relevant_order = item.order
# Check if order is from that user before deletion.
if not relevant_order.customer == request.user
# return some 403 error
item.delete()
# After deletion of the item check if there are items left.
if not relevant_order.orderitem_set.all()
relevant_order.delete()
return render(request, "store/deletecartitem.html", {})
I used your code so you can incorporate the changes quickly.
Answered By - coderiot
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.