Ошибка :Forbidden (CSRF токен отсутствует или неверен.) при использовании django rest framework

Я использую в своем учебном проекте django rest framework.Я получаю ошибку 403 Forbidden (CSRF token missing or incorrect, когда я пытаюсь сохранить с помощью метода POST. Вот мой код html

<form id = "product_form" method = "post">
    {% csrf_token %}
    <input type = "hidden" name = "id" id = "id">
    <p>Назвние:<input name = "name" id = "name"></p>
    <p><input type = "reset" value = "Oчистить"></p>
    <input type = "submit" value = "Сохранить">
</form>

Вот мой код js:

let productUpdater = new XMLHttpRequest();
productUpdater.addEventListener('readystatechange', () => {

        if (productUpdater.readyState == 4) {
            if ((productUpdater.status == 200) || (productUpdater.status == 201)) {
                listLoad();
                name.form.reset();
                id.value = '';
            } else {
                window.alert(productUpdater.statusText)
            }
        }
    }
);


name.form.addEventListener('submit', (evt) => {
    evt.preventDefault();
    // let vid = id.value, url, method;
    let vid = id.value;
    if (vid) {
        url = 'http://127.0.0.1:8000/books/api_category/' + vid + '/';
        method = 'PUT';
    } else {
        url = 'http://127.0.0.1:8000/books/api_category/';
        method = 'POST';
    }
    let data = JSON.stringify({id: vid,nameCategory: name.value});
    productUpdater.open(method, url, true);
    productUpdater.setRequestHeader('Content-Type', 'application/json');
    productUpdater.send(data);
})

Вот мой views.py:

@api_view(['GET', 'POST'])
def api_products(request):
    if request.method == 'GET':
        productsAll = CategoryMaskarad.objects.all()
        serializer = CategorySerializer(productsAll, many=True)
        return Response(serializer.data)
    elif request.method == 'POST':
        serializer = CategorySerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'PUT', 'PATCH', 'DELETE'])
def api_rubric_detail(request, pk):
    product = CategoryMaskarad.objects.get(pk=pk)
    if request.method == 'GET':
        serializer = CategorySerializer(product)
        return Response(serializer.data)
    elif request.method == 'PUT' or request.method == 'PATCH':
        serializer = CategorySerializer(product, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    elif request.method == 'DELETE':
        product.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

Вот мой urls.py:

 path('api_category/<int:pk>/', api_rubric_detail),
 path('api_products/', api_products),
 path('api/drf-auth/', include('rest_framework.urls'))

Я добавил последний путь и вошел в систему. В api интерфейсе появилась возможность добавлять в api методом post, но с помощью js в моем html я не могу добавить данные.Помогите, пожалуйста

при передаче данных из формы в django rest framework, вы не добавляете тег csrf_token перед формами, а передаете его в качестве заголовка при отправке api post на вашу конечную точку. Добавьте эту строку после

productUpdater.setRequestHeader('Content-Type', 'application/json');

productUpdater.setRequestHeader('X-CSRF-Token', 'abcdef');

У меня есть такой вариант. Он работает.Я добавил в js файл:

name.form.addEventListener('submit', (evt) => {
    evt.preventDefault();
    // let vid = id.value, url, method;
    let vid = id.value, url, method;
    if (vid) {
        url = 'http://127.0.0.1:8000/books/api_category/' + vid + '/';
        method = 'PUT';
    } else {
        url = 'http://127.0.0.1:8000/books/api_category/';
        method = 'POST';
    }
    let data = JSON.stringify({id: vid, nameCategory: name.value});
    productUpdater.open(method, url, true);
    productUpdater.setRequestHeader('Content-Type', 'application/json');
    productUpdater.setRequestHeader('X-CSRFToken', csrftoken);
    productUpdater.send(data);
})

и я добавил в html файл:

<script>
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
</script>
Вернуться на верх