【问题标题】:DRF class based view parse dataObj ids from datatables基于 DRF 类的视图从数据表中解析 dataObj id
【发布时间】:2021-03-31 23:58:45
【问题描述】:

我正在使用数据表,我的目标是删除选定的行。我可以选择行并获取它们的 ID。 #countbuttonids 按钮可以完美地做到这一点并向我发送警报。但是,当我尝试将此数据发布到我的自定义 DRF 端点时,我在删除数据数组中具有 ID 的对象时遇到问题。

以下两次尝试及其相关的错误消息。

views.py 1

# https://www.django-rest-framework.org/tutorial/3-class-based-views/

class APIDeleteEntries(generics.RetrieveUpdateDestroyAPIView):
    queryset = Entry.objects.all()
    serializer_class = EntrySerializer

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

错误信息 1

assert lookup_url_kwarg in self.kwargs, (
AssertionError: Expected view APIDeleteEntries to be called with a URL keyword argument named "pk". Fix your URL conf, or set the `.lookup_field` attribute on the view correctly.
[22/Dec/2020 10:11:21] "DELETE /api/delete-entries/ HTTP/1.1" 500 114337

views.py 2

# https://www.django-rest-framework.org/tutorial/3-class-based-views/

class APIDeleteEntries(generics.RetrieveUpdateDestroyAPIView):
    queryset = Entry.objects.all()
    serializer_class = EntrySerializer

    def delete(self, request, *args, **kwargs):
        entry_ids = self.kwargs['id']
        return entry_ids.destroy(request, *args, **kwargs)

错误信息 2

    entry_ids = self.kwargs['id']
KeyError: 'id'

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="countbuttonids">Count row ids</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>
            </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' );
    } );

    $('#countbuttonids').click( function () {
       alert( table.rows('.selected').data().pluck('id').toArray() );
    } );

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

        // Get ids of selected rows to pass to url
        var dataObj = table.rows('.selected').data().pluck('id').toArray();

        $.ajax({
            // DRF endpoint specific delete object
            // TEST:success
            "url": '/api/entries/795/',
            // # TODO:
            // Send to custom endpoint to delete list of endpoints
            // TEST:error entry_ids = self.kwargs['id']
            "url": '/api/delete-entries',
            "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 %}

urls.py

...
path('api/delete-entries/', APIDeleteEntries.as_view(), name="delete-entries"),

【问题讨论】:

  • 我仍在努力,非常感谢任何帮助!

标签: javascript django django-rest-framework datatables


【解决方案1】:

您遇到的问题是 DRF 找不到应该是 id(pk) 的查找字段,因此您在 AJAX 请求中的 Url 必须在该表单上 url:your url/id/ 但是我在您的代码中注意到您在 ajax 中覆盖了 url

 "url": '/api/entries/795/',
            // # TODO:
            // Send to custom endpoint to delete list of endpoints
            // TEST:error entry_ids = self.kwargs['id']
            "url": '/api/delete-entries',  ### override happens here it must be commented or deleted and you must add id ti be changes every time you request
id

所以你必须做的每一个请求都是 url:"url": '/api/entries/id-here/', 如果没有找到 id,它将引发未找到错误(404),否则它将删除

【讨论】:

    猜你喜欢
    • 2020-04-04
    • 2014-01-22
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    • 1970-01-01
    • 1970-01-01
    • 2019-01-28
    • 2013-02-04
    相关资源
    最近更新 更多