Как выполнять 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 для выполнения вызовов сервера. Это значительно облегчит вам жизнь.

Вернуться на верх