Search code examples
pythondjangomodelsone-to-one

Django Deleting just one object from OneToOneField and retrieve it


I'm building a simple website with Django where users have a cart. They can add items to cart and after that they can buy them (adding the purchases to another model). Well, I'm new to Django and I have one problem with that. After buy the products I delete the cart object and create another object cart new empty. The first time that I buy the products all is fine, but the second time that I try to pay items. I always get empty Cart object although if I check the database I can see that there're the right products there...

I will leave here my django's models:

from __future__ import unicode_literals

from django.db import models
from django.contrib.auth.models import User

class Cart(models.Model):
    user = models.ForeignKey(User, null=True)
    items = models.ManyToManyField(Item, null=True)
    money = models.FloatField(default=0)
    def __str__(self):
        aux = ""
        for item in self.items.all():
            aux += "\n"+"["+item.name+"]" + str(item.price)+ " " + item.type + " " + str(item.description)+"\n"
        aux += "\n\nTotal Price: "+str(self.money)
        return aux

class Client(models.Model):
    user = models.OneToOneField(User)
    cart = models.OneToOneField(Cart, null=True, on_delete=models.SET_NULL)
    money = models.FloatField(default=0)
    def __str__(self):
        return "["+str(self.user)+"]"+str(self.money)

And my pay, buy and add function's:

@login_required
def addCart(request):
    selectedItems =[]
    for key in request.POST:
         if key.startswith("checkbox"):
             identificador = int(request.POST[key])
             item = Item.objects.get(id=identificador)
             client = Client.objects.get(user=request.user.id)
             if client.cart == None:
                 user = User.objects.get(username=request.user.username)
                 cart = Cart.objects.create(user=user)
                 client.cart = cart
                 client.cart.items.add(item)
                 client.cart.money += item.price
                 client.cart.save()
             else:
                 client.cart.items.add(item)
                 client.cart.money += item.price
                 client.cart.save()
    return HttpResponseRedirect(request.META["HTTP_REFERER"])

@login_required
def buy(request):
    client = Client.objects.get(user=request.user.id)
    if client.cart != None:
        products = client.cart.items
        total = client.cart.money
    else:
        products = client.cart
        total = 0
    context = {
        'cart':products,
        'money':total
    }
    return render(request, 'mediacloud/buy.html', context)

def pay(request):
    client = Client.objects.get(user=request.user.id)
    products = client.cart.items.all()
    result = False
    if client.money >= client.cart.money:
        client.money -= client.cart.money
        client.save()
        client.cart.money = 0.0
        client.cart.save()
        for product in products:
            Purchases.objects.create(item=product, user=str(request.user))
            result = True
        user = User.objects.get(username=request.user.username)
        Cart.objects.filter(user=user).delete()
        cart = Cart.objects.create(user=user)
        client.cart = cart
        client.cart.save()
    context = {
        'result':result
    }
    return render(request, 'mediacloud/result.html', context)

I don't see why I'm not retrieving any item from the client's cart... The first time that the user add something to the cart all is fine, the problem comes when I delete the cart object and create a new cart object for the user Maybe I've my models into a wrong way... If someone could point me into the right direction I'd be grateful


Solution

  • Since you're essentially trying to clear the items out of the cart, instead of deleting the Cart object and recreating it. Try clearing out the ManyToManyField to items on the Cart object:

    Cart.objects.filter(user=user)[0].items.clear()