Thanks ahead of time for the help. I am trying to check if a cart object exists when a user visits the "myCart" page. If it does not, it should then create a new instance and use the user's id as a foreign key for reverse lookup. So I used the exists() method in an if statement. What's weird is that instead of executing the else block, it just throws me an error telling me the object doesn't exist. The test user doesn't have a cart object associated with it yet and that's obvious. What I don't understand is why it isn't triggering my else statement. Maybe I have been coding too long and need some sleep and that's why I'm missing it. Anyway if you guys could take a look for me I'd really appreciate it. :)
The Error: Weird Error
#the views.py file for this app:
def myCart(request):
context = {}
if request.user.is_authenticated:
owner = request.user.id
if Cart.objects.get(cart_owner=owner).exists():
context['cart'] = cart
return render(request, 'cart/myCart.html', context)
else:
cart = Cart(cart_owner=owner)
context['cart'] = cart
return render(request, 'cart/myCart.html', context)
else:
return HttpResponseRedirect(reverse("login"))
def update_cart(request):
if request.user.is_authenticated:
owner = request.user.id
cart = Cart.objects.get(cart_owner=owner)
productID = request.GET['id']
product = Product.objects.get(pk=productID)
if not product in cart.products.all():
cart.products.add(product)
else:
cart.products.remove(product)
new_total = 0.00
for item in cart.products.all():
new_total = float(item.priceNotax)
cart.total = new_total
cart.save()
return HttpResponseRedirect(reverse("myCart"))
else:
return HttpResponseRedirect(reverse("login"))
The cart model:
class Cart(models.Model):
cart_owner = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
products = models.ManyToManyField(Product, null=True, blank=True)
total = models.DecimalField(max_digits=100, decimal_places=2, default=0.00)
timestamp = models.DateTimeField(auto_now_add=False, auto_now=True)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
active = models.BooleanField(default=True)
def __unicode__(self):
return "Cart id: %s" %(self.id)
CodePudding user response:
By using .get(…)
, you retrieve the Cart
, and if that is done successfully, .exists()
will not work since a model object has no .exists()
object.
You can work with .get_or_create(…)
[Django-doc] to retrieve, or create a Cart
object in case no such Cart
exists:
from django.contrib.auth.decorators import login_required
@login_required
def myCart(request):
context = {}
context['cart'], __ = Cart.objects.get_or_create(cart_owner=request.user)
return render(request, 'cart/myCart.html', context)
Note: It is normally better to make use of the
settings.AUTH_USER_MODEL
[Django-doc] to refer to the user model, than to use theUser
model [Django-doc] directly. For more information you can see the referencing theUser
model section of the documentation.
Note: You can limit views to a view to authenticated users with the
@login_required
decorator [Django-doc].
CodePudding user response:
.get()
will throw an error if exactly 1 object was not found. Instead, replace it with .filter()
and then you can check .exists()
Hence, change Cart.objects.get(cart_owner=owner).exists()
to Cart.objects.filter(cart_owner=owner).exists()
Alternatively, you can use a try-except block which is technically a bit faster:
try:
thepost = Content.objects.get(name="test")
except Content.DoesNotExist:
thepost = None