Reputation: 651
I have a shoppinglist app. I want that when the user clicks on "add to shopping list" the item is saved to the shopping list.
How can I do that?
in the template I wrote:
<a href="javascript:{document.getElementById('add_item').submit()}" class="btn btn-primary btn-block">Add to
shopping list
</a>
<form action="{% url 'add_to_shopping_list' product.id %}" id="add_item" method="POST">
{% csrf_token %}
<input type="hidden">
</form>
in urls.py
I dispaced the urls like this:
urlpatterns = [
path('add_to_shopping_list/<int:pk>', views.add_to_shopping_list, name='add_to_shopping_list'),
]
this calls the view add_to_shopping_list
where I want create a ShoppingItem object and to link this to the Product object. The problem is that I don't want to redirect the user anywhere, but just stay on the same page without refreshing. But the view wants me to return an HtmlResponse, or I get this error:
The view shoppinglist.views.add_to_shopping_list didn't return an HttpResponse object. It returned None instead.
Is the idea correct? If yes how can I solve this problem? Thanks
EDIT
here is the view.py
, this is just the idea, I could not debug it
from . models import ShoppingItem
from products.models import Product
def add_to_shopping_list(request, pk):
item = Product.objects.get(pk=pk)
shopping_list = request.user.shopping_lists.all()[0]
product = ShoppingItem(name=item.name, list=shopping_list, price=item.price)
product.save()
return ???
The Product object already exists, but I need to create a ShoppingItem object that is associated to that shopping list that belongs to that user.
Upvotes: 0
Views: 1533
Reputation: 651
So I solved it in this way:
view.py
def add_to_shopping_list(request):
if request.method == 'GET':
product_id = request.GET.get('product_id')
product = Product.objects.get(pk=product_id)
if ShoppingItem.objects.filter(product__id=product_id).exists():
item = ShoppingItem.objects.filter(product__id=product_id)[0]
item.quantity +=1
item.save()
else:
shopping_list = request.user.shopping_lists.all()[0]
product = ShoppingItem(name=product.name, list=shopping_list, price=product.price, product=product)
product.save()
return HttpResponse('updated')
else:
return HttpResponse('unsuccessful')
main.js uses jQuery
$('.add-to-list').click(function () {
var id;
var url;
id = $(this).attr("data-catid");
url = $(this).attr("to_java");
console.log(id);
$.ajax(
{
type: "GET",
url: url,
data: {
product_id: id
},
success: function (data) {
$('#add-to-list' + id).removeClass('btn btn-primary btn-block');
$('#add-to-list' + id).addClass('btn btn-success btn-block');
$('#add-to-list' + id).text('Added to the shopping list');
}
})
});
template.html
<a to_java="{% url 'add_to_shopping_list' %}" id="add-to-list{{ product.id }}" class="add-to-list btn btn-primary btn-block" data-catid="{{ product.id }}">
Add to shopping list
</a>
Upvotes: 0
Reputation: 820
In template use:
<button id="add-item-btn">Add item</button>
<form action="{% url 'add_to_shopping_list' product.id %}" id="add-item" method="POST">
{% csrf_token %}
</form>
<script>
function getCookie(name) { //function for getting cookie
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return r ? r[1] : undefined;
}
function ajax(method, url, data, callback){ //function for ajax request
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function(){
if (this.readyState == 4){
if(callback != null) callback(this.status, this.responseText);
}
};
xhttp.open(method, url, true);
xhttp.setRequestHeader("X-CSRFToken", getCookie("csrftoken")); //set CSRF header
xhttp.send(data);
}
document.getElementById("add-item-btn").onclick = function(){ //create onclick event for button
let url = document.getElementById("add-item").getAttribute("action"); //get action attribute from form
ajax("POST", url, null, null); //send request
};
</script>
The form tag is here just to store data and you can replace it with something else.
In view.py
return for example updated
text, you can use this response to display Added! message to user:
from django.http import HttpResponse
from . models import ShoppingItem
from products.models import Product
def add_to_shopping_list(request, pk):
item = Product.objects.get(pk=pk)
shopping_list = request.user.shopping_lists
product = ShoppingItem(name=item.name, shopping_list=shopping_list)
product.save()
return HttpResponse('updated')
Upvotes: 1