Как правильно использовать Fetch в JavaScript и Django?
Я пытаюсь сделать декодер METAR, как показано на рисунке: 
Я использую fetch в Vanilla js и планирую отправлять введенный код в представление Django. Из представления Django будут взяты декодированные данные и отображены в шаблоне.
views.py
def ToolsPageView(request):
if request.method == "POST":
jsonData = json.loads(request.body)
metarCode = jsonData.get('Metar')
return JsonResponse("Success", safe=False)
return render(request, 'app/tools.html')
urls.py
...
path("tools", views.ToolsPageView, name="tools")
tools.html
<div class="metar-code-decode">
<form method="POST" action="{% url 'tools' %}" id="metar-form">
{% csrf_token %}
<input type="text" placeholder="Enter METAR: " id="metar-value"> <br>
<input type="submit" id="metar-button">
</form>
</div>
tool.js
function getDecodedMetar() {
let formButton = document.querySelector("#metar-button");
formButton.onclick = function (e) {
let metarCode = document.querySelector("#metar-value").value;
sendMetar(metarCode);
//e.preventDefault();
//getMetar(metarCode);
};
}
function sendMetar(metarCode) {
fetch('/tools', {
method: "POST",
headers: {
"X-CSRFToken": getCookie("csrftoken"),
},
body: JSON.stringify({
Metar: metarCode,
}),
});
}
Я использовал тот же код для POST, используя fetch, где мне нужно было позволить пользователю обновить свой профиль. И это сработало. Но это не работает, и ошибка продолжает меняться время от времени после перезапуска сервера. При первой попытке не было выдано никакой ошибки, и сервер также показал, что запрос POST выполняется. А последняя ошибка, которую я получаю, звучит так: "Для того чтобы разрешить сериализацию объектов, не являющихся диктами, установите параметр safe в False". Я получаю одно и то же снова и снова, даже после установки safe=False внутри JsonResponse(). Стоит отметить, что request при преобразовании в request.json() выдает ошибку.
Я неправильно использую fetch? Если да, то как правильно?
Я не уверен, что вы правильно поняли поток. Идея заключается в том, что кнопка при нажатии вызывает функцию (fetch), которая отправляет данные в представление, которое декодирует их и отправляет обратно в JavaScript, так что они могут быть отображены без перезагрузки всей страницы .
Думаю, это может помочь:
let formButton = document.querySelector("#metar-button");
// When the button is clicked,
formButton.onClick = function(e) {
// do NOT send the form the usual way
e.preventDefault();
let metarCode = document.querySelector("#metar-value").value;
// Run the function that will send the code to the ToolsPageView
sendMetar(metarCode);
}
async function sendMetar(metarCode) {
const response = await fetch('/tools', {
method: "POST",
headers: {
"X-CSRFToken": getCookie("csrftoken"),
},
body: JSON.stringify({
'Metar': metarCode,
}),
})
.then(response => response.json())
.then(data => {
console.log(data);
// extract the decoded value from the data sent back from the view
// display it by targeting the element in your html that you want
// to display it
});
}
А с вашей точки зрения,
def ToolsPageView(request):
if request.method == "POST":
jsonData = json.loads(request.body)
metarCode = jsonData.get('Metar')
# Remove the original JsonResponse
# return JsonResponse("Success", safe=False)
# and INSTEAD,
# Send the code back to the JavaScript
# I don't THINK you need safe=False here?
return JsonResponse({'MetarCode': metarCode})
return render(request, 'app/tools.html')