当我加载超过 50000 行时,我在 django 中使用 js 的数据表非常慢

Posted

技术标签:

【中文标题】当我加载超过 50000 行时,我在 django 中使用 js 的数据表非常慢【英文标题】:My datatable using js in django is very slow when i load more than 50000 rows 【发布时间】:2021-10-21 20:41:03 【问题描述】:

我的模特:

class PartyMaster(models.Model):
    party_name = models.CharField(max_length=200,null=True, blank=True)
    email = models.EmailField(null=True, blank=True)
    contact = models.CharField(max_length=100,null=True, blank=True)
    address = models.CharField(max_length=350,null=True, blank=True)
    country = models.CharField(max_length=30,null=True, blank=True)
    sub_country = models.ForeignKey(CountryCategory,max_length=200,on_delete=models.CASCADE,null=True,blank=True,related_name='party_sub_country')
    state = models.CharField(max_length=50,null=True, blank=True)
    city = models.CharField(max_length=50,null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.party_name + " "+ self.email

我的视图:在我的模型中有 50 000+ 行

def party_list(request):
    parties = PartyMaster.objects.all()
    context = 
        'parties':parties,
    
    return render(request,'party_master/party_edit.html',context)

我的模板:

% extends 'base.html' %
% block title % Party List's % endblock %

% block body %

<div class="container">
    <a href="% url 'add_party' %" class="btn btn-primary button_class mt-5">Party Master Form</a>
<div class="py-3">
    <div class="table-responsive">
    <table class="table table-striped  table-hover text-center table-responsive-sm" id="party_table">
        <thead class="table-head">
            <tr>

                <th scope="col">Party Name</th>
                <th scope="col">Email</th>
                <th scope="col">Contact</th>
                <th scope="col">Country</th>
                <th scope="col">Sub Country</th>
            </tr>
        </thead>
        <tbody>
            % for party in parties %
            <tr>

                <td class="pt-3">party.party_name</td>
                <td class="pt-3">party.email</td>
                <td class="pt-3">party.contact</td>
                <td class="pt-3">party.country</td>
                <td class="pt-3">party.sub_country.country_category</td>
            </tr>
            % endfor %

        </tbody>
    </table>

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

% endblock %

% block js %

    <!-- Datatable -->

    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.25/css/jquery.dataTables.css">
    <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.js"></script>
    <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
    <script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>
    <script src="https://cdn.datatables.net/buttons/1.7.1/js/dataTables.buttons.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
    <script src="https://cdn.datatables.net/buttons/1.7.1/js/buttons.html5.min.js"></script>
    <script src="https://cdn.datatables.net/buttons/1.7.1/js/buttons.print.min.js"></script>



<script>

    $(document).ready(function() 
        $('#party_table').DataTable( 
            dom: 'Bfrtip',
            "pageLength": 50,
            buttons: [
                
                    extend: 'excelHtml5',
                    exportOptions: 
                        columns: [ 0, 1, 2, 3, 4 ]
                    
                ,
                
                    extend: 'pdfHtml5',
                    exportOptions: 
                        columns: [ 0, 1, 2, 3, 4 ]
                    
                ,
            ]
         );
     );
</script>


% endblock %

如何通过服务器端处理加载数据?我很困惑如何在文档中使用帮助来实现。请从头开始提供完整的实现。

还有什么替代方法可以建议吗?

【问题讨论】:

查看以下注释here,它试图提供服务器端概述,并澄清官方文档。请特别注意与服务器端处理一起使用的 JSON 请求和响应数据结构(在答案中链接到) - 请记住,您的 Django 代码将负责所有排序、过滤和分页逻辑。这假定了一种纯 ajax 方法 - 当然还有其他方法。 只是补充:“请从头开始提供完整的实现。” - 如果你幸运的话,有人可能会为你完成所有这些编码。但这通常不是 Stack Overflow 的工作方式。尝试就您可能面临的特定问题提出特定问题。 【参考方案1】:

在使用 Datatables 处理大型数据集时,您希望避免在 TR 级别使用迭代,而是希望在 DataTable 定义中设置数据属性。

https://mail.datatables.net/forums/discussion/32107/how-to-load-an-array-of-json-objects-to-datatables

您可以通过在脚本标签中创建一个 JSON 对象然后迭代各方并构建 JSON 来做到这一点。

以这种方式定义数据源时,数据表的呈现速度更快。

另一种方法是使用服务器端 AJAX (https://datatables.net/examples/data_sources/ajax),但您会找到的大多数示例都将使用 php

对于您的代码,它将是这样的:

<script>
let data = [
% for party in parties %
    
      "party_name": " party.party_name ",
      "email": " party.email ",
      "contact": " party.contact ",
      "country": " party.country ",
      "country_category": " party.sub_country.country_category "
    % if not forloop.last %,% endif %
% endfor %
];

    $(document).ready(function() 
        $('#party_table').DataTable( 
            dom: 'Bfrtip',
            "pageLength": 50,
            buttons: [
                
                    extend: 'excelHtml5',
                    exportOptions: 
                        columns: [ 0, 1, 2, 3, 4 ]
                    
                ,
                
                    extend: 'pdfHtml5',
                    exportOptions: 
                        columns: [ 0, 1, 2, 3, 4 ]
                    
                ,
            ],
            data: data,
            columns: [
                 data: 'party_name',
                 data: 'email',
                 data: 'contact',
                 data: 'country',
                 data: 'country_category'
            ]
         );
     );
</script>

因此,在第一部分中,您定义 JSON 结构,然后根据 data 参数将其传递到数据表配置中,然后使用 columns 参数告诉它使用数据的顺序

为了帮助调试和查看从您的数据库中提取了哪些记录,请改用它,这将显示源中记录的 PK,以便您可以对数据库进行交叉检查

<script>
let data = [
% for party in parties %
    
      /* PK= party.pk  */
      "party_name": " party.party_name ",
      "email": " party.email ",
      "contact": " party.contact ",
      "country": " party.country ",
      "country_category": " party.sub_country.country_category "
    % if not forloop.last %,% endif %
% endfor %
];

    $(document).ready(function() 
        $('#party_table').DataTable( 
            dom: 'Bfrtip',
            "pageLength": 50,
            buttons: [
                
                    extend: 'excelHtml5',
                    exportOptions: 
                        columns: [ 0, 1, 2, 3, 4 ]
                    
                ,
                
                    extend: 'pdfHtml5',
                    exportOptions: 
                        columns: [ 0, 1, 2, 3, 4 ]
                    
                ,
            ],
            data: data,
            columns: [
                 data: 'party_name',
                 data: 'email',
                 data: 'contact',
                 data: 'country',
                 data: 'country_category'
            ]
         );
     );
</script>

【讨论】:

它复制所有行并且还显示警告和数据未正确显示。我将通过链接附上图片。 并且您在 HTML 部分中删除了迭代器,因此您的 tbody 标记应该为空。所以只需&lt;tbody&gt;&lt;/tbody&gt; 它复制所有行并且还显示警告和数据未正确显示。我将通过链接附上图片。 link 我更正了示例,我的剪贴板内容错误,所以我输入了 master_bill 而不是。对于重复项,如果您查看呈现的源,条目是否在 JSON 对象中出现两次?如果是这样,请检查您的数据库是否有重复记录,并在 PK 中添加 JS 注释。例如。将/* party.pk */ 添加到循环中,这样您就可以看到它正在拾取哪些记录 我已经用一个完整的例子更新了答案,添加了 PK 进行调试以使其更清晰

以上是关于当我加载超过 50000 行时,我在 django 中使用 js 的数据表非常慢的主要内容,如果未能解决你的问题,请参考以下文章

如何有效地将大文件加载到 IndexedDB 存储中?我的应用程序在超过 100,000 行时崩溃

当我在 django 中运行 Bootstrap 轮播时,它不会显示图像,但是当我在普通 HTML 文件中使用它们时它们加载得非常好

在容器中运行时,重新加载telegraf配置的最佳方法。

当我在 tableView 的最后一行单击“更多数据...”时,TableView 不会重新加载数据

Django 迁移失败

当从多个分表查询超过 4 亿行时,BigQuery 的预期查询响应性能是多少?