Ajax jQuery serialize() & serializeArray() textarea 未以 Django 形式提交

Posted

技术标签:

【中文标题】Ajax jQuery serialize() & serializeArray() textarea 未以 Django 形式提交【英文标题】:Ajax jQuery serialize() & serializeArray() textarea not submitting in Django form 【发布时间】:2021-12-07 06:32:43 【问题描述】:

我有一个表单,我正在尝试通过 AJAX 和 jQuery 将数据提交到 Django API。通过 Django 管理员提交工作正常,但通过表单,textarea 字段是导致问题的一个原因。我有一个没有 textarea 的类似表格,它工作正常。 textarea 内容未提交,我不知道为什么。这是表格:

<form id="addMaintenanceRecordsForm" action="">
    % csrf_token %
    <div class="mb-3">
        <div class="row">
            <div class="col-md-12">
                <label>Title <span style="color: #dd0000;">*</span></label>
                <input type="text" class="form-control" name="maintenance_title" placeholder="Enter Title" id="mr-title" required>
            </div>
        </div>
    </div>
    <div class="mb-3">
        <div class="row">
            <div class="col-md-12">
                <label>Details <span style="color: #dd0000;">*</span></label>
                <textarea class="form-control" id="mr-summary" name="summary" placeholder="Describe the nature of maintenance repair..." rows="3" required></textarea>
            </div>
        </div>
    </div>
    <div class="mb-3">
        <div class="row">
            <div class="col-md-12">
                <label>Repair Status <span style="color: #dd0000;">*</span></label>
                <select class="form-select" name="repair_status" id="mr-status" aria-label="Default select example" placeholder="Repair Status" required>
                    <option selected disabled>Choose...</option>
                    <option value="Complete">Complete</option>
                    <option value="Ongoing">Ongoing</option>
                </select>
            </div>
        </div>
    </div>
     
    <button type="submit" class="btn btn-soft-primary btn-sm" id="mr-create">Create New Record</button>
    <button type="button" class="btn btn-soft-secondary btn-sm">Cancel</button>
</form>

这是我的 jQuery 代码

$(function()  
        $('#addMaintenanceRecordsForm').on('submit', function(e)  
            e.preventDefault();

            console.log($("#addMaintenanceRecordsForm").serializeArray());

            let url = "http://127.0.0.1:8000/api/maintenance/add/";

            $.ajax(
                type : 'POST',
                url : url,
                data : $("#addMaintenanceRecordsForm").serializeArray(),
                dataType: "json",
                success: function(data)
                    alert("New Maintenance Records Added!");
                    location.reload();
                ,
                error:function(data)
                    alert("Maintenance Records Not Added!");
                    location.reload();
                
            );

        );
    );

我不断收到此错误:

Bad Request: /api/maintenance/add/
POST http://127.0.0.1:8000/api/maintenance/add/ 400 (Bad Request)

在控制台上我得到了这个:


    "name": "csrfmiddlewaretoken",
    "value": "jZ7Y2WrJB67xrkP34U53ngf11cu4ju1nvzlQ29Krtqv5ehkjuami0uwvyCrFdXAs"


    "name": "maintenance_title",
    "value": "Pipe Leakages"


    "name": "summary",
    "value": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."


    "name": "repair_status",
    "value": "Ongoing"

而 django CMD 我得到了这样的字典

<QueryDict: 'csrfmiddlewaretoken': ['LmbrIAnh7fJcAjjQ0hnEiwSujdFTJfLgXWpjINGZZz7KngO6qxETVK9YQDCuDIkl'], 'maintenance_title': ['Pipe Leakages'], 'summary': ['Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'], 'repair_status': ['Ongoing']>

我尝试过其他解决方案,例如:

data : $("#addMaintenanceRecordsForm").serialize(),

data : $("#addMaintenanceRecordsForm input, #addMaintenanceRecordsForm textarea").serializeArray(),

data : $("#addMaintenanceRecordsForm").find('input', 'select').serializeArray(),

$('#mr-create').on('click', function(e)  
    e.preventDefault();

但它们似乎都不起作用。 textarea 没有序列化可能是什么问题?

【问题讨论】:

您说它返回 400 Bad Request,您是否打开了调试模式?如果是这样,您可以使用 Postman 访问相同的 API 并查看它返回的内容吗? Django 调试模式应该有助于返回更多信息。 @MarkBarrett 调试模式已开启。我按照你的建议做了,邮递员返回"maintenance_title":["This field is required."],"summary":["This field is required."],"repair_status":["This field is required."],然后是Bad Request: /api/maintenance/add/ [20/Oct/2021 18:13:55] "POST /api/maintenance/add/ HTTP/1.1" 400 301,我不确定这是否是你要求的信息。我已经通过邮递员输入了新的原始数据并且它有效。所以在我看来端点工作得很好。甚至http://127.0.0.1:8000/api/maintenance/add/ 也可以。 @MarkBarrett 我读过其他关于 SO 的文章:source 1、source 2 或 source 3,但还没有解决方案。它的文本区域就是问题所在。我今天已经完成了 5 种不同功能的表单,没有一个有 textarea,它们都可以完美运行。这是第一个带有文本区域的。 你在使用 Django REST 吗? @MarkBarrett 是的,我是。我从做一个简单的实验。我将 【参考方案1】:

在您的代码中,您表明您正在将表单打印到控制台,如下所示:

console.log($("#addMaintenanceRecordsForm").serializeArray());

你说它会产生这样的输出:


    "name": "csrfmiddlewaretoken",
    "value": "jZ7Y2WrJB67xrkP34U53ngf11cu4ju1nvzlQ29Krtqv5ehkjuami0uwvyCrFdXAs"


    "name": "maintenance_title",
    "value": "Pipe Leakages"


    "name": "summary",
    "value": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."


    "name": "repair_status",
    "value": "Ongoing"

如果它是使用 Django REST 的 JSON API,您仍然需要与此类似的结构:


    "csrfmiddlewaretoken": "jZ7Y2WrJB67xrkP34U53ngf11cu4ju1nvzlQ29Krtqv5ehkjuami0uwvyCrFdXAs",
    "maintenance_title": "Pipe Leakages",
    "summary": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
    "repair_status": "Ongoing"

您收到 400 Bad Request 的原因是因为您发送的 JSON 在每个字段的顶层都没有键,这意味着 Django REST 无法找到它们。

我建议您研究一下 serializerArray 的实际作用,因为它可能不是您想要的。

相反,我建议使用表单每个字段的值在 javascript 中构造 JSON 对象,例如:


   "maintenance_title": $("#mr-title").value(),
   "repair_status": $("#mr-status").value()

或者也许尝试再次使用“.serialize()”来查看它打印到控制台的内容。您收到错误请求并表示所有字段都丢失的事实意味着它不仅仅发生在 Textarea 上。

要进行测试,请在 Postman 中构建您自己的对象,这与我所拥有的类似,然后查看错误是否消失。

【讨论】:

我在邮递员上创建了自己的对象,提交时没有错误。我在 console.log 中用serialize() 替换了serializeArray(),得到了csrfmiddlewaretoken=5ya3MJFvKS9V190RkB50t5hVLk4sJFS0h8oVMWYdCcxtO6v7KRmf6jypiK13D8r5&amp;maintenance_title=New%20Paint&amp;summary=Lorem%20ipsum%20dolor%20sit%20amet%2C%20consectetur%20adipiscing%20elit%2C%20sed%20do%20eiusmod%20tempor&amp;repair_status=Ongoing 在 django 服务器上我收到了&lt;QueryDict: 'csrfmiddlewaretoken': ['5ya3MJFvKS9V190RkB50t5hVLk4sJFS0h8oVMWYdCcxtO6v7KRmf6jypiK13D8r5'], 'maintenance_title': ['New Paint'], 'summary': ['Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor'], 'repair_status': ['Ongoing']&gt; 我创建了自己的 JSON 对象,例如data: "maintenance_title": $("#mr-title").val(), "summary": $("#mr-summary").val(),"repair_status": $("#mr-status").val(),但表单仍然没有提交。我仍然收到 400 错误。 好的。你能像我上面展示的那样尝试在 JS 中构造你自己的对象吗 我做到了data: "maintenance_title": $("#mr-title").val(), "summary": $("#mr-summary").val(),"repair_status": $("#mr-status").val() but the form is still not submitting. I'm still getting a 400 error. 那么服务器收到了什么?

以上是关于Ajax jQuery serialize() & serializeArray() textarea 未以 Django 形式提交的主要内容,如果未能解决你的问题,请参考以下文章

jquery-ajax中的serialize()

jQuery ajax - serialize() 方法-输出序列化表单值

jQuery ajax()使用serialize()提交form数据

jQuery ajax()使用serialize()提交form数据

jQuery ajax中serialize()方法增加其他参数

ajax中push,在jQuery serialize()或serializeArray()中添加/ push()值到Ajax POST