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.