I'm trying to add products in my basket without refreshing the page and i have
urls:
app_name = 'basket'
urlpatterns = [
path('', views.BasketView.as_view(), name='summary'),
path('/add', views.BasketView.post, name='basket_add'),
]
views:
class BasketView(generic.list.ListView):
template_name = 'basket/basket.html'
model = Category
def post(self, request, *args, **kwargs):
data = request.POST
print(data)
return 'something'
html (+JS):
...
<button onclick="basket_add(this)" id="{{ item.id }}"></button>
...
<script>
function send_productId(id){
var request = new XMLHttpRequest();
request.open('POST', '{% url 'basket:basket_add' %}', true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
const data = {
id: id,
csrfmiddlewaretoken:'{{ csrf_token }}',
action: "POST",
};
request.send(data);
};
function basket_add(obj){
send_productId(obj.id);
};
</script>
after pressing the button i get this error
Forbidden (CSRF token missing.): /basket/add
So how can i at least print data correctly or do i need to do it the other way?
Here is the solution to your error. You can add csrf_exempt to your post method. This will allow you to submit the form without csrf token.
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
@method_decorator(csrf_exempt, name='dispatch')
class BasketView(generic.list.ListView):
template_name = "basket/basket.html"
model = Category
def post(self, request, *args, **kwargs):
data = request.POST
print(data)
return "something"
PS: Inherit from CreateView or just from View class if you are using it to just create a new object. And in urls.py use your path something like this
path("/add", BasketCreateView.as_view(), name='basket_add')
instead of your current path.
And have a look at javascript fetch to make server calls. It will make your life much easier.