Как выполнять POST-запросы в Django с помощью JS?
Я пытаюсь добавить товары в корзину без обновления страницы и у меня
Урлы:
app_name = 'basket'
urlpatterns = [
path('', views.BasketView.as_view(), name='summary'),
path('/add', views.BasketView.post, name='basket_add'),
]
просмотров:
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>
после нажатия кнопки я получаю эту ошибку
Запрещено (CSRF-токен отсутствует.): /basket/add
>
Итак, как я могу хотя бы правильно вывести данные или мне нужно сделать это по-другому?
Вот решение вашей ошибки. Вы можете добавить csrf_exempt
к вашему методу post
. Это позволит вам отправить форму без 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: Наследуйте от CreateView
или просто от класса View
, если вы используете его для простого создания нового объекта. А в urls.py
используйте свой путь примерно так
path("/add", BasketCreateView.as_view(), name='basket_add')
вместо вашего текущего пути.
И посмотрите на javascript fetch для выполнения вызовов сервера. Это значительно облегчит вам жизнь.