如何在 JavaScript 和 Django 中正确使用 Fetch?

How to correctly use Fetch in JavaScript and Django?

我正在尝试制作一个 METAR 解码器,如图所示:

我在 Vanilla js 中使用 fetch,我打算将输入的代码发送到 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 中我不得不让用户更新 his/her 配置文件。这奏效了。但是,这不起作用,并且在重新启动服务器后错误不断变化。第一次尝试时,没有产生任何错误,服务器还显示正在发出 POST 请求。我得到的最新错误是“为了允许序列化非字典对象,将安全参数设置为 False”。即使在 JsonResponse() 中设置 safe=False 之后,我也一次又一次地得到同样的结果。值得注意的是,request 转换为 request.json() 时会出错。

我是不是用错了fetch?如果是,正确的做法是什么?

我不确定你的流程是否正确。这个想法是,单击按钮时,将调用一个函数(获取),该函数将数据发送到视图,视图将对其进行解码并将其发送回 JavaScript,以便可以显示 [=18] =]无需重新加载整个页面。

我认为这可能有帮助:

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')