Django -> Объект 'WSGIRequest' не имеет атрибута 'data' -> Ошибка в json.loads(request.data)

Я видел похожий вопрос, но ответ на него довольно расплывчатый. Я создал представление на основе функции для updateItem. Я пытаюсь получить json данные для загрузки на основе моего запроса. но получаю ошибку -> у объекта нет атрибута 'data'

ФайлViews.py:

def updateItem(request):  
    
    data = json.loads(request.data)
    
    productId = data['productId']
    action = data['action']
    print("productID", productId, "action", action)
    customer = request.user.customer
    product = Product.objects.get(id=productId)
    order, created = Order.objects.get_or_create(customer=customer,complete=False)

    orderItem, created = OrderItem.objects.get_or_create(order=order, product=product)
    
    
    if action == 'add':
        orderItem.quantity = (orderItem.quantity + 1)
    elif action == 'remove':
        orderItem.quantity = (orderItem.quantity - 1)
    orderItem.save()
    
    if orderItem.quantity <= 0:
        orderItem.delete()
        
    return JsonResponse("Item was added!", safe=False)

JS File:

function updateUserOrder(productId, action) {
    console.log('User is logged in...');
    let url = '/update_item/';

    fetch(url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRFToken': csrftoken,
        },
        body: JSON.stringify({ productId: productId, action: action }),
    })
        .then((res) => {
            return res.json();
        })
        .then((data) => {
            console.log('data', data);
        });
}

urls python file:

urlpatterns = [
    path("",views.store,name="store"),
    path("cart/",views.cart,name="cart"),
    path("checkout/",views.checkout,name="checkout"),
    path("update_item/",views.updateItem,name="update_item"),
]

Ошибка, похоже, также возникает в моей функции fetch в JS-файле. С моим методом POST. Не могу найти решение, что я делаю не так?

Попытка:

data = json.loads(request.body)

Потому что в запросе нет data, так как вы передаете данные в виде body: JSON.stringify({ productId: productId, action: action }),

Основная проблема заключается в том, что вы пытаетесь получить доступ к 'request.data', а такого атрибута не существует. Вы хотите получить данные из POST-запроса. (Также, обратите внимание, что хорошей практикой является использование в представлениях и переменных имен в форме snake_case, тогда как camelCase используется для классов):

def updateItem(request):  
    
    data = json.loads(request.POST.get('data'))
    ...
        
    return JsonResponse("Item was added!", safe=False)

Хотя, чтобы завершить свой ответ, я должен сказать, что у меня были проблемы с вашей JS-функцией, когда токен csrf не был правильно присоединен. Мое тестовое решение:

views.py

from django.shortcuts import render
from django.http import JsonResponse
import json

def update_item(request):
    return render(request, 'update_item.html', {})

def update_item_ajax(request): 
    data = json.loads(request.POST.get('data'))
    print(data)
    ...
    
    return JsonResponse({'message': '"Item was added!"'}, safe=False)

# output of update_item_ajax print
{'productId': 1, 'action': 'myaction'}

urls.py

from django.urls import path
from core import views

app_name = 'core'

urlpatterns = [
    path('update/item/', views.update_item, name='update-item'),
    path('update/item/ajax/', views.update_item_ajax, name='update-item-ajax'),
]

update_item.html

{% extends 'base.html' %}

{% block content %}
<button onclick="updateUserOrder(1, 'action')"> update item </button>
{% endblock %}

{% block script %}
    <script>
        function updateUserOrder(productId, action) {
            console.log('User is logged in...');
            let url = "{% url 'core:update-item-ajax' %}";
            
            var payload = {
                productId: productId,
                action: action
            };
            var data = new FormData();
            data.append( 'data' , JSON.stringify( payload ) );
            data.append('csrfmiddlewaretoken', '{{ csrf_token }}');

            fetch(url, 
            {   
                method: 'POST',
                body: data,
            })
            .then(function(res){ return res.json(); })
            .then(function(data){ console.log(data); });
        }
    </script>
{% endblock %}

Атрибутом является request.body, а не request.data.

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