django-rest-framework 数据表列分表

Posted

技术标签:

【中文标题】django-rest-framework 数据表列分表【英文标题】:django-rest-framework datatables columns break table 【发布时间】:2021-02-20 19:00:03 【问题描述】:

第 1 部分

我让我的数据表与 obj 迭代一起工作,但我正在移动到 DRF-datatables.. 虽然我让示例站点运行没有问题,但我的实际实现却让我很头疼。基本上,我整个周末都在展示一个似乎正在加载数据的表格(因为分页显示了正确的信息)但我的行都是空白的:https://i.imgur.com/ImA23Zo.png

然后我尝试在脚本中添加“列”部分,这打破了整个表格:https://i.imgur.com/ykwf58P.png

如果我将 ajax 调用更改为

"ajax": "/api/entry/?format=datatables",

然后我得到最紧密的工作表:https://i.imgur.com/p5G5uzk.png - 但是问题仍然是行是空的,如果我添加列,那么一切都会中断。

我哪里错了?我也没有收到任何错误消息,因此很难调试数据表​​。

可能是第 2 部分..

我什至需要使用 DRF 数据表吗?我的最终目标是能够选择多行,然后编辑所有这些条目的交易。

最终目标示例

    选择 3 笔交易 点击表格顶部某处的下拉菜单 从该下拉列表中选择交易PK 点击保存 表格显示最新数据

entry_list.html

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

<!-- 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>


<!-- Content Row -->
<div class="row">
    <div class="col-md-12">
        <table id="entrytable"
               class="table-hover table display"
               align="center"
               style="width:100%">
            <thead>
            <tr role="row">
                <th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
                    colspan="1" aria-label="" style="">ID
                </th>
                <th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
                    colspan="1" aria-label="" style="">Date
                </th>
                <th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
                    colspan="1" aria-label="" style="">Trade
                </th>
                <th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
                    colspan="1" aria-label="" style="">Type
                </th>
                <th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
                    colspan="1" aria-label="" style="">Symbol
                </th>
                <th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
                    colspan="1" aria-label="" style="">Amount
                </th>
                <th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
                    colspan="1" aria-label="" style="">Price
                </th>
                <th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
                    colspan="1" aria-label="" style="">Fee
                </th>
                <th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
                    colspan="1" aria-label="" style="">Reg Fee
                </th>
                <th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
                    colspan="1" aria-label="" style="">Ref
                </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 = [];

    $("#entrytable").DataTable(
        "order": [[ 1, "desc" ]],
        "processing": true,
        "serverSide": true,
        "ajax": 
            "url": "/api/entry/?format=datatables",
            "type": "POST",
            "beforeSend": function(xhr) 
                xhr.setRequestHeader("X-CSRFToken", " csrf_token|escapejs ");
            
        ,
        "columns": [
            "data": "pk",
            "data": "date",
            "data": "trade.id",
            "data": "entry_type",
            "data": "symbol",
            "data": "amount",
            "data": "price",
            "data": "fee",
            "data": "reg_fee",
            "data": "transaction_id",
        ]
        "rowCallback": function( row, data ) 
            if ( $.inArray(data.DT_RowId, selected) !== -1 ) 
                $(row).addClass('selected');
            
        
    );

    $('#entrytable tbody').on('click', 'tr', function () 
        var id = this.id;
        var index = $.inArray(id, selected);

        if ( index === -1 ) 
            selected.push( id );
         else 
            selected.splice( index, 1 );
        

        $(this).toggleClass('selected');
     );
 );


</script>

% endblock %

序列化器.py

class EntrySerializer(serializers.ModelSerializer):
    class Meta:
        model = Entry
        fields = '__all__'

Views.py

class EntryViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows groups to be viewed or edited.
    """
    queryset = Entry.objects.all()
    serializer_class = EntrySerializer
    permission_classes = [permissions.IsAdminUser]
    filter_backends = (DjangoFilterBackend, OrderingFilter,)

models.py

class Entry(models.Model):
    ENTRY = 'entry'
    EXIT = 'exit'
    ENTRY_TYPE_CHOICES = [
        (ENTRY, 'Entry'),
        (EXIT, 'Exit'),
        # (DIVIDEND_RECEIVED, 'Dividend Received'),
        # (DIVIDEND_SOLD, 'Dividend Sold'),
    ]

    class Meta:
        verbose_name = "Entry"
        verbose_name_plural = "Entries"

    trade = models.ForeignKey(Trade, on_delete=models.CASCADE, null=True, blank=True)
    date = models.DateTimeField(null=True, blank=True, default=datetime.datetime.now)
    amount = models.FloatField(null=True)
    price = models.FloatField(null=True)
    fee = models.FloatField(null=True, blank=True)
    entry_type = models.CharField(max_length=5, choices=ENTRY_TYPE_CHOICES, default=ENTRY)
    reg_fee = models.FloatField(null=True, blank=True)
    transaction_id = models.CharField(max_length=100, null=True, blank=True)
    symbol = models.ForeignKey(Symbol, on_delete=models.SET_NULL, blank=True, null=True)
    created_by = models.ForeignKey(User, null=True, blank=True, editable=False, on_delete=models.CASCADE)

【问题讨论】:

【参考方案1】:

我什至需要使用 DRF 数据表吗?

如果您正在使用服务器端处理(就像您目前一样),您只需要 DRF 数据表。除非您需要支持大型数据集(1000 行),否则您可能不需要服务器端处理。

如果您的结果集大小在 100 秒以内,请坚持使用模板渲染。

我的最终目标是能够选择多行,然后编辑所有这些条目的交易。

使用 Datatables 和 JQuery 绝对可以做到这一点。 datatables-select 插件会有所帮助。但这很棘手(如您所见)。在开始编码之前尝试阅读并理解文档和示例 - 从长远来看,这肯定会节省您的时间。

更新

如果它不工作......

    尝试自行调用 API URL。它是否返回正确的数据?

    确保列名与从 API 调用返回的名称相匹配。这可能很棘手 - 确保您清楚 API 响应的结构,并且您已声明 columns correctly。

    也许从一个简单的列开始,然后先让它发挥作用。然后添加新列。

    drf datatables 中设置断点 - 逐步检查是否有任何失败或错误。

    下载并运行DRF DataTables example app - 有一个有效的实现可能会帮助您找出问题所在。

它肯定会起作用(我已经在 Django / DRF Datatables 中使用过数据表)——但一开始设置起来可能会很棘手。

【讨论】:

我将处理 1000 行,很快就会有 10,000 行。感谢您指出了这一点。因此,这似乎是正确的下坡路。我想我已经阅读了每个文档页面两次。我不完全确定错误来自哪里,所以我正在尝试寻找更多示例项目。第三个 Imgur 链接显示我已经可以选择行,但没有填充数据。我觉得这超级奇怪 Waaa 感谢 Matthew 在这个问题上一直支持我。我感觉自己像一只迷路的小狗。第一步是可行的(尽管我曾一次完成了上述所有步骤)。我觉得必须有一个列,所以我运行 DRF 并使用 127.0.0.1:8000/api/entry 并确保所有列与列和 对齐。呼..是时候回到原来的问题了***.com/questions/64623613/…lol(也许我会再次见到你)

以上是关于django-rest-framework 数据表列分表的主要内容,如果未能解决你的问题,请参考以下文章

将可编辑字段作为 Django-Rest-Framework Serializer 的验证数据方法传递

django-rest-framework 是不是提供管理站点来管理模型?

如何使用 django-rest-framework 中的序列化器将相似数据合并到自定义字段中?

在 HTML 页面或模板中使用 Django-REST-Framework 从在 Django 中创建的 API 获取/显示 API 数据

python django-rest-framework 3.3.3 更新嵌套序列化程序

django-rest-framework-从零开始-2-序列化类serializers.Serializer的使用