Django Rest 框架数据表删除

Posted

技术标签:

【中文标题】Django Rest 框架数据表删除【英文标题】:Django Rest Framework Datatables DELETE 【发布时间】:2021-02-28 09:39:21 【问题描述】:

问题

我想将 ID 列表发送到 Django Rest Framework API url(这是 rest_framework 路由器的默认值)。到目前为止,一切都在进行到发送 ID 的工作。当我单击删除按钮时,DELETE 调用会转到 127.0.0.1:8000/api/entries/_id_/,并且不会添加选择删除的正确 ID。

来自服务器的错误消息

我相信这或多或少是显而易见的:

detail: "Not found."
detail: "Not found."

entry_list.html

% extends "dashboard/base.html" %
% load i18n %
% block content %

<style>


table.dataTable tbody tr.odd.selected 
 background-color:#acbad4


table.dataTable tbody tr.even.selected 
 background-color:#acbad5



</style>

<!-- Page Heading -->
<div class="d-sm-flex align-items-center justify-content-between mb-4">
    <h2 class="text-gray-800">% block title %% trans "Imported Entries" %% endblock %</h2>
    <a role="button" class="btn btn-success" href="% url 'import' %"><i
            class="fas fa-plus-circle"></i> Import New Entires</a>
</div>

<button id="countbutton">Count rows</button>
<button id="deletebutton">Delete rows</button>

<!-- Content Row -->
<div class="row">
    <div class="col-md-12">
        <table id="entrytable"
               class="table-hover table display table-bordered"
               align="center"
               style="width:100%">
            <thead>
            <tr role="row">
                <th>id</th>
                <th>date</th>
                <th>amount</th>
                <th>price</th>
                <th>fee</th>
                <th>entry_type</th>
                <th>reg_fee</th>
                <th>transaction_id</th>
                <th>trade</th>
                <th>symbol</th>
                <!--                <th>created_by</th>-->
            </tr>
            </thead>

        </table>
    </div>
</div>

% endblock %


% block js %

<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.css"/>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/dataTables.bootstrap4.min.css"/>


<!--https://datatables.net/examples/server_side/select_rows.html-->
<!--<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.min.css"/>-->

<script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.22/js/dataTables.bootstrap4.min.js"></script>


<script>

$(document).ready(function() 

//    var selected = [];

    var table = $('#entrytable').DataTable(
        "order": [[ 0, "desc" ]],
        "processing": true,
        "ajax": "/api/entries/?format=datatables",
        "columns": [
            
                "data": "id",
                "render": function ( data, type, row, meta ) 
                    return '<a type="button" class="" target="_blank" href="' + data + '">' + data + ' </a>';
                
            ,
            "data": "date",
            "data": "amount",
            "data": "price",
            "data": "fee",
            "data": "entry_type",
            "data": "reg_fee",
            "data": "transaction_id",
            
                "data": "trade",
                "render": function ( data, type, row, meta ) 
                    if (data) 
                      return '<a type="button" target="_blank" class="" href="/trade/' + data + '"> ' + data + ' </a>';
                     else 
                      // show nothing
                    
                ,
                "defaultContent": "",
            ,
            
                "data": "symbol",
                "defaultContent": "",
            ,
           // "data": "created_by",
            ],


    );

    $('#entrytable tbody').on( 'click', 'tr', function () 
        $(this).toggleClass('selected');
     );

    $('#countbutton').click( function () 
        alert( table.rows('.selected').data().length +' row(s) selected' );
     );


    $('#deletebutton').click( function () 
        var selectedRows = table.rows("selected": true);

        var dataObj = 
            // parse selectedRows to get object ids
            table.rows("selected":true).data().pluck('ID');
        

        $.ajax(
            "url": '/api/entries/_id_/',
            "type": 'DELETE',
            "beforeSend": function(xhr) 
                xhr.setRequestHeader("X-CSRFToken", " csrf_token|escapejs ");
            ,
            "contentType": 'application/json',
            "data": dataObj,
            "success": function (data, status, xhr) 
                // remove the selected rows from the view
                table.row('.selected').remove().draw( false );
            
        )
     );


 );



</script>

% endblock %

【问题讨论】:

【参考方案1】:

您需要开始分解逻辑以找出不起作用的地方。

    查看浏览器控制台(“网络”)选项卡,查看发送的 DELETE 请求是什么。是否以您期望的格式发送?

    自行进行 DELETE 调用。您可以使用 curl、Postman 或(甚至更好)Django Rest Framework test 等来单独隔离 API 调用。确保这会按预期删除行。如果您在后端运行调试器,这将真正加快发现任何问题的速度。一旦这工作正常,您就可以调试前端了。

由于您暗示没有将 id 添加到 ajax 请求中,因此您可以使用浏览器开发人员工具 Javascript 调试器在 deletebutton 点击逻辑中设置断点。逐步执行此操作,您应该能够找出问题的根源。

另外,只是一个想法,但你打电话给pluck('ID') - 这应该是pluck('id') 吗?

【讨论】:

你在这里成为一支单人军队并无济于事,有时我会盯着一个问题数周,因为我无法反复思考。 1. 那是“详细信息:”未找到。“”因为删除转到 URL 而不替换 Id 变量。 2. 我一直在尝试使用 DRF 测试,它很有帮助,很好的建议,但不是我目前坚持的地方。 JS 调试也很有帮助,使用鼠标事件点击断点。将 ID 更改为 id 不会改变任何内容,但 dataObj 总是会为我打破页面。那 var 和 selectedRows var 是必要的吗?似乎可以用 1 来完成。 如果有帮助,我今天会加入chat

以上是关于Django Rest 框架数据表删除的主要内容,如果未能解决你的问题,请参考以下文章

在 django rest 框架中删除多个对象

Django rest框架:防止一个用户删除/编辑/查看ModelViewSet中的其他用户

如何在 django rest 框架中访问获取请求数据

python Django Rest_Framework框架 APIView介绍与序列化器详解(图文并茂版)

python Django Rest_Framework框架 APIView介绍与序列化器详解(图文并茂版)

Django rest框架拉入外部json数据