I've multiple items that can be added to the cart by clicking the respective button. Each item is a form having information about itemid and, the 'addtocart' button is the submit button for the form.
I'm using ajax to make changes in the DB and then reload the page to reflect them.
Html
<script type="text/javascript">
$(document).on('submit','.addtocart',function(e){
e.preventDefault();
var a=$(this).find('input[name=itemid]').val();
$.ajax({
type:'POST',
url:'addtocart',
data:{
itemid:a,
'csrfmiddlewaretoken': $('[name="csrfmiddlewaretoken"]').val()
}
});
setTimeout(() => { document.location.reload(true);} , 100);
});
</script>
views.py
@login_required(login_url='/userhome')
def addtocart(request):
if request.method == "GET":
return redirect('/')
else:
product_id = request.POST['itemid']
product_quantity = 1
cart = usercart.objects.all().filter(user_id = request.user.id, product_id = product_id )
try:
if cart[0] is not None:
cart = usercart.objects.get(user_id = request.user.id, product_id=product_id)
cart.product_quantity+=1
cart.save()
else:
cart = usercart(product_id=product_id, user_id=request.user.id, product_quantity=product_quantity)
cart.save()
except IndexError:
cart = usercart(product_id=product_id, user_id=request.user.id, product_quantity=product_quantity)
cart.save()
return redirect('checkout')
I want to redirect to the login page ('/userhome') if the user is not logged in and addtocart button is clicked. I've tried wrapping my Js inside
{% if user.is_authenticated %}
<script>
...
</script>
{% endif %}
But due to this, the user cannot see the products before logging in. I want a user to see products without logging but addtocart button should work in both situations, redirecting to users who are not logged in and adding products for the user who are logged in.
You should use the statusCode
callbacks for your ajax
method. This will also prevent any issues where the POST request takes longer than 100ms and the page is reloaded before the database is updated.
You are also returning a redirect in the request to the checkout page, ajax requests should not recieve redirect responses usually. You should instead return a success status code, here I use http responses, but JSON responses would be better.
return HttpResponse("", status=200)
If the user is not logged in return a response code associated with being unauthorised
return HttpResponse("", status=401)
Use the above methods instead of using the @login_required
decorator as it will return a redirect.
You can then handle this in the ajax method using the statusCode
callbacks:
$.ajax({
type:'POST',
url:'addtocart',
data:{
itemid:a,
'csrfmiddlewaretoken': $('[name="csrfmiddlewaretoken"]').val()
},
statusCode: {
200: function() {
// Success! Reload the page
document.location.reload(true);
},
401: function() {
// Unauthorized, redirect to home
window.location.href = "/userhome";
},
}
});