• bootstrap-table+Django: 服务端分页(包括搜索查询功能)


    bootstrap-table+Django: 服务端分页(包括搜索查询功能)

    1.分页方式:

    bootstrap-table提供两种分页方式,client和server,即客户端和服务端分页;

    特点:

    • client端分页:后台返回所有数据,前台翻页时不再请求后台。
    • server端分页:后台根据前台每次翻页时传递的参数,进行切片查询数据,每次只返回对应页面的数据。

    弊端:

    client端分页:

    1. 后台一次查询所有数据,对服务器造成压力交大;
    2. 当页面存在bootstrap-switch时,由于我是在bootstrap-table中的onLoadSuccess加载完表格后渲染switch开关,
    3. 当使用client分页时,只进行了一次后台查询,也就是执行了一次onLoadSuccess函数,所以除了第一页开关按钮正常,其他页面都没有渲染出开关。

    server端分页:
        暂无

    2.实现代码:

    2.1 前端

    在你的base模板中引入相应的包即可使用,这里代码就不全贴出来了

    {% extends "base.html" %}
    {% load static %}
    {% block main %}
        <style>
            .table th, .table td {
                text-align: center;
                vertical-align: middle !important;
                word-break: break-all;
            }
        </style>
        <!-- Basic Setup -->
        <section class="section">
            <div class="container mt-100">
                <div class="row justify-content-center">
                    <div class="col-12 text-center">
                        <div class="section-title mb-4 pb-2">
                            <h4 class="title mb-4">xxxxxxxx列表</h4>
                        </div>
                    </div><!--end col-->
                </div><!--end row-->
    
                <div id="toolbar">
                    <div class="form-inline" role="form">
                        <input class="btn btn-soft-primary btn-sm" type="button" id="btn1" value="显示所有列"
                               onclick="showAllCol()">
                        <a href="{% url 'feature_extension:new_feature' %}" target="_blank"  style="margin-left: 5px"><input
                                class="btn btn-soft-secondary btn-sm" type="button" id="btn2" value="增加新申请"
                                href="{% url 'feature_extension:new_feature' %}"></a>
                        <!-- 自定义搜索查询 -->
                        <div class="input-group" style="left: 5px"><input id="search-keyword"
                                                                           class="form-control search-input" type="search"
                                                                           placeholder="Search" autocomplete="off">
                            <div class="input-group-append">
                                <button id="search-button" class="btn btn-soft-primary btn-sm" type="button" name="search"
                                        title="Search">
                                    <i class="fa fa-search"></i></button>
                            </div>
                        </div>
                    </div>
                </div>
                <!-- data feature index pagination -->
                <table id="table"
                       class="table-sm small"
                       data-pagination="true"
                       data-buttons-class="soft-primary btn-sm"
                       data-sort-name="created_date"
                       data-sort-order="desc"
                       data-remember-order="true"
    
                       data-show-fullscreen="true"
                       data-show-columns="true"
                       data-show-columns-toggle-all="true"
                       data-show-export="true"
    
                       data-click-to-select="true"
                       data-toolbar="#toolbar"
                       style="table-layout: fixed;height: auto"
                >
                    <thead class="thead-light">
                </table>
            </div>
        </section>
    {% endblock %}
    
    {% block script %}
        <!-- JS for download table-->
        <script>
            var $table = $('#table')
            $(function () {
                $('#toolbar').find('select').change(function () {
                    $table.bootstrapTable('destroy').bootstrapTable({
                        exportDataType: $(this).val(),
                        exportTypes: ['excel', 'xml', 'csv', 'txt', 'sql'],
                        columns: [
                            {
                                field: 'state',
                                checkbox: true,
                                visible: $(this).val() === 'selected'
                            }
                        ]
                    })
                }).trigger('change')
            })
        </script>
        <!-- JS for pagination -->
        <script>
            var $articlesTable = $('#table').bootstrapTable('destroy').bootstrapTable({
                url: '/feature_extension/feature_extension_list/',
                method: 'GET',
                dataType: "json",
                uniqueId: 'id',  //每一行的唯一标识,一般为主键列
                striped: false,  //是否显示行间隔色
                cache: false,
                sortName: 'no',
                sortable: true,
                sortOrder: 'desc',
                sidePagination: "server",
                undefinedText: '--',
                singleSelect: true,
                toolbar: '#toolbar',  //工具按钮用哪个容器
                showToggle: true,    //是否显示详细视图和列表视图的切换按钮
                cardView: false,    //是否显示详细视图
                strictSearch: true,
                clickToSelect: true,
                pagination: true,  //是否显示分页(*)
                showRefresh: true,  //是否显示刷新按钮
                pageNumber: 1,  //初始化加载第一页,默认第一页
                pageSize: 10,  //每页的记录行数(*)
                pageList: [10, 20, 50, 100, 'all'],
                paginationPreText: "<",
                paginationNextText: ">",
                queryParamsType: "",
                queryParams: function (params) {
                    var query_params = {
                        'pageSize': params.pageSize,
                        'pageNumber': params.pageNumber,
                        'search_kw': $('#search-keyword').val(), // 查询框中的参数传递给后台
                        'sortName': params.sortName,
                        'sortOrder': params.sortOrder
                    };
                    return query_params;
                },
                columns: [
                    {
                        field: 'no',
                        title: '序号',
                        align: 'center',
                        halign: 'center',
                        width: '60px',
                        visible: true,
                        sortable: true,
                        formatter: function (value, row, index) {
                            var result = "";
                            result += '+ row.id + '/" target="_blank">' + row.no + ''
                            return result
                        }
                    },
                    {
                        field: 'id',
                        title: 'DB_Id',
                        align: 'center',
                        halign: 'center',
                        width: '70px',
                        visible: false,
                        sortable: true,
                        formatter: function (value, row, index) {
                            var result = "";
                            result += '+ row.id + '/" target="_blank">' + row.id + ''
                            return result
                        }
                    },
                    {
                        field: 'title',
                        title: '主题',
                        align: 'left',
                        halign: 'center',
                        width: '180px',
                        visible: true,
                        formatter: function (value, row, index) {
                            var result = "";
                            result += '+ row.id + '/" target="_blank">' + row.title + ''
                            return result
                        }
                    },
                    {
                        field: 'owner',
                        title: '申请人ID',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                    },
                    {
                        field: 'full_name',
                        title: '申请人',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: true,
                    },
                    {
                        field: 'category',
                        title: '类别',
                        align: 'left',
                        halign: 'center',
                        width: '80px',
                        visible: true,
                    },
                    {
                        field: 'description',
                        title: '描述',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                    },
                    {
                        field: 'oecc_domestic',
                        title: 'OCL国内',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                        formatter: function (value, row, index) {
                            var result = "";
                            for (var i = 0; i < row.oecc_domestic.length; i++) {
                                result += ''+row.oecc_domestic[i].name+'; '
                            }
                            return result
                        }
                    },
                    {
                        field: 'oecc_oversea',
                        title: 'OCL海外',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                        formatter: function (value, row, index) {
                            var result = "";
                            for (var i = 0; i < row.oecc_oversea.length; i++) {
                                result += ''+row.oecc_oversea[i].name+'; '
                            }
                            return result
                        }
                    },
                    {
                        field: 'oe_domestic',
                        title: 'OE国内',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                        formatter: function (value, row, index) {
                            var result = "";
                            for (var i = 0; i < row.oe_domestic.length; i++) {
                                result += ''+row.oe_domestic[i].name+'; '
                            }
                            return result
                        }
                    },
                    {
                        field: 'oe_oversea',
                        title: 'OE海外',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                        formatter: function (value, row, index) {
                            var result = "";
                            for (var i = 0; i < row.oe_oversea.length; i++) {
                                result += ''+row.oe_oversea[i].name+'; '
                            }
                            return result
                        }
                    },
                    {
                        field: 'note',
                        title: '备注',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                    },
                    {
                        field: 'tech_ss',
                        title: '受影响子系统',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: true,
                        formatter: function (value, row, index) {
                            var result = "";
                            for (var i = 0; i < row.tech_ss.length; i++) {
                                result += ''+row.tech_ss[i].name+'; '
                            }
                            return result
                        }
                    },
                    {
                        field: 'solution',
                        title: '技术可行性',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                    },
                    {
                        field: 'complexity',
                        title: '复杂度',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                    },
                    {
                        field: 'tech_comment',
                        title: '技术团队建议',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: true,
                    },
                    {
                        field: 'mkt_decision',
                        title: '市场部决策',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                        formatter: function (value, row, index) {
                            {#console.log(row)#}
                            var result = "";
                            {#for (var i = 0; i < row.tech_ss.length; i++) {#}
                            {#    result += ''+row.tech_ss[i].name+'; '#}
                            {#}#}
                            return result
                        }
                    },
                    {
                        field: 'mkt_priority',
                        title: '优先级',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                    },
                    {
                        field: 'mkt_comment',
                        title: '市场团队建议',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: true,
                    },
                    {
                        field: 'status',
                        title: '进度状态',
                        align: 'center',
                        halign: 'center',
                        width: '80px',
                        visible: true,
                    },
                    {
                        field: 'plan',
                        title: '计划发布时间',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                    },
                    {
                        field: 'exe_owner',
                        title: '项目负责人',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                    },
                    {
                        field: 'exe_owner_mail',
                        title: '邮箱',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                    },
                    {
                        field: 'exe_leader_mail',
                        title: '经理邮箱',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                    },
                    {
                        field: 'cr_number',
                        title: 'CR',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                    },
                    {
                        field: 'cn_number',
                        title: 'CN',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                    },
                    {
                        field: 'mrd_date',
                        title: 'MRD',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                    },
                    {
                        field: 'created_date',
                        title: '创建日期',
                        align: 'center',
                        halign: 'center',
                        width: '100px',
                        visible: true,
                        sortable: true,
                    },
                    {
                        field: 'attachments',
                        title: '附件',
                        align: 'left',
                        halign: 'center',
                        width: '100px',
                        visible: false,
                        formatter: function (value, row, index) {
                            var result = "";
                            for (var i = 0; i < row.attachments.length; i++) {
                                result += '+ row.attachments[i].id + '">' + row.attachments[i].filename + ';
    ' } return result } }, { title: '操作', align: 'center', halign: 'center', width: '50px', visible: true, formatter: function (value, row, index) { var result = ""; result += '+ row.id + '/" target="_blank">   ' result += '+ row.id + ')">' return result } } ], onLoadError: function (data) { console.log("数据加载失败!", "错误提示"); $.messager.alert({title: '提示', msg: '数据加载失败!', icon: 'warning', top: 200}); }, }); // 搜索查询按钮触发事件 $("#search-button").click(function () { console.log($('#search-keyword').val()) $('#table').bootstrapTable(('refresh')); }) // 回车执行搜索 $("#search-keyword").bind('keyup', function (event) { console.log($('#search-keyword').val()) $('#table').bootstrapTable(('refresh')); }) </script> <!-- JS for delete data --> <script> function del_feature_ext(feature_id) { console.log(feature_id) $.messager.confirm({ title: '提示', msg: '是否确认删除该条数据?', top: 200, fn: function (r) { if (r) { $.ajax({ url: server_url + '/feature_extension/del_feature/' + feature_id, method: 'GET', processData: false, contentType: false, cache: false, success: function (data) { console.log("data:" + data); console.log("data:" + data.status); if (data.status === 200) { {#$.messager.alert({title: '提示', msg: data.msg, icon: 'warning', top: 200,});#} $.messager.show({ title: '提示', msg: data.msg, showType: '', timeout: 500, style: {top: 200} }); console.log("data:" + data.msg); {#window.setTimeout(window.location = server_url + '/cp_index/', 2500);#} window.setTimeout("window.location=server_url+'/feature_extension'", 600); return } console.log(data) $.messager.alert({title: '提示', msg: '权限不足或服务请求异常,数据无法删除!', icon: 'warning', top: 200}); }, //请求失败,包含具体的错误信息 error: function (data) { console.log('error' + data.msg); $.messager.alert({title: '提示', msg: '请求服务错误或当前网络不佳!', icon: 'warning', top: 200}); } }); } } }); } </script> <!-- JS for show/hide column--> <script> var showFlag = true function showAllCol() { if (showFlag) { $table.bootstrapTable('showColumn', 'category'); $table.bootstrapTable('showColumn', 'description'); $table.bootstrapTable('showColumn', 'full_name'); $table.bootstrapTable('showColumn', 'owner'); $table.bootstrapTable('showColumn', 'oecc_domestic'); $table.bootstrapTable('showColumn', 'oecc_oversea'); $table.bootstrapTable('showColumn', 'oe_domestic'); $table.bootstrapTable('showColumn', 'oe_oversea'); $table.bootstrapTable('showColumn', 'note'); $table.bootstrapTable('showColumn', 'tech_ss'); $table.bootstrapTable('showColumn', 'solution'); $table.bootstrapTable('showColumn', 'complexity'); $table.bootstrapTable('showColumn', 'tech_comment'); $table.bootstrapTable('showColumn', 'mkt_decision'); $table.bootstrapTable('showColumn', 'mkt_priority'); $table.bootstrapTable('showColumn', 'mkt_comment'); $table.bootstrapTable('showColumn', 'plan'); $table.bootstrapTable('showColumn', 'exe_owner'); $table.bootstrapTable('showColumn', 'exe_owner_mail'); $table.bootstrapTable('showColumn', 'exe_leader_mail'); $table.bootstrapTable('showColumn', 'cr_number'); $table.bootstrapTable('showColumn', 'cn_number'); $table.bootstrapTable('showColumn', 'attachments'); showFlag = false } else { $table.bootstrapTable('hideColumn', 'description'); $table.bootstrapTable('hideColumn', 'owner'); $table.bootstrapTable('hideColumn', 'oecc_domestic'); $table.bootstrapTable('hideColumn', 'oecc_oversea'); $table.bootstrapTable('hideColumn', 'oe_domestic'); $table.bootstrapTable('hideColumn', 'oe_oversea'); $table.bootstrapTable('hideColumn', 'note'); $table.bootstrapTable('hideColumn', 'solution'); $table.bootstrapTable('hideColumn', 'complexity'); $table.bootstrapTable('hideColumn', 'mkt_decision'); $table.bootstrapTable('hideColumn', 'mkt_priority'); $table.bootstrapTable('hideColumn', 'plan'); $table.bootstrapTable('hideColumn', 'exe_owner'); $table.bootstrapTable('hideColumn', 'exe_owner_mail'); $table.bootstrapTable('hideColumn', 'exe_leader_mail'); $table.bootstrapTable('hideColumn', 'cr_number'); $table.bootstrapTable('hideColumn', 'cn_number'); $table.bootstrapTable('hideColumn', 'attachments'); showFlag = true } } </script> {% endblock %}
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448
    • 449
    • 450
    • 451
    • 452
    • 453
    • 454
    • 455
    • 456
    • 457
    • 458
    • 459
    • 460
    • 461
    • 462
    • 463
    • 464
    • 465
    • 466
    • 467
    • 468
    • 469
    • 470
    • 471
    • 472
    • 473
    • 474
    • 475
    • 476
    • 477
    • 478
    • 479
    • 480
    • 481
    • 482
    • 483
    • 484
    • 485
    • 486
    • 487
    • 488
    • 489
    • 490
    • 491
    • 492
    • 493
    • 494
    • 495
    • 496
    • 497
    • 498
    • 499
    • 500
    • 501
    • 502
    • 503
    • 504
    • 505
    • 506
    • 507
    • 508
    • 509
    • 510
    • 511
    • 512
    • 513
    • 514
    • 515
    • 516
    • 517
    • 518
    • 519
    • 520
    • 521
    • 522
    • 523
    • 524
    • 525
    • 526
    • 527
    • 528
    • 529
    • 530
    • 531
    • 532
    • 533
    • 534
    • 535
    • 536
    • 537
    • 538
    • 539
    • 540
    • 541
    • 542
    • 543
    • 544
    • 545
    • 546
    • 547
    • 548
    • 549
    • 550
    • 551
    • 552
    • 553
    2.1.3 Django后端

    APIView使用了DRF框架,django内置的是View
    查询功能可根据自己的需求更改

    模型表models.py

    class feature_ext(BaseModel):
        # properties for applicant
        title = models.CharField(max_length=200, verbose_name='主题', blank=False)
        owner = models.CharField(max_length=50,
                                 blank=True,
                                 verbose_name='申请人ID')
        full_name = models.CharField(max_length=50,
                                     blank=False,
                                     verbose_name='申请人')
        category = models.CharField(max_length=10,
                                    blank=False,
                                    choices=[('', '请选择'), ('NEW', '新需求'), ('NONSTD', '非标转标准化')],
                                    verbose_name='类别')
        description = models.TextField(blank=False, verbose_name='描述')
    
        oecc_domestic = models.ManyToManyField(OeccDomestic, blank=True, verbose_name="OCL国内产品:")
        oecc_oversea = models.ManyToManyField(OeccOversea, blank=True, verbose_name="OCL海外产品:")
        oe_domestic = models.ManyToManyField(OeDomestic, blank=True, verbose_name="OE国内产品:")
        oe_oversea = models.ManyToManyField(OeOversea, blank=True, verbose_name="OE海外产品:")
        note = models.TextField(blank=True, verbose_name='备注')
    
        # properties for evaluator
        # Technical Review 技术团队评估
        tech_ss = models.ManyToManyField(subsystem, blank=True, verbose_name="受影响子系统:")
        solution = models.CharField(max_length=10,
                                    blank=True,
                                    choices=[('', '请选择'), ('Y', '有'), ('N', '无')],
                                    verbose_name='技术可行性-成熟的技术方案(有/无)')
        complexity = models.CharField(max_length=10,
                                      blank=True,
                                      choices=[('', '请选择'), ('H', '高'), ('M', '中'), ('L', '低')],
                                      verbose_name='复杂度')
        tech_comment = models.TextField(blank=True, verbose_name='技术团队建议')
    
        # Marketing Review 产品管理团队评估
        mkt_decision = models.CharField(max_length=10,
                                        blank=True,
                                        choices=[('', '请选择'), ('GO', '同意'), ('GO_A', '同意并有行动项'),
                                                 ('MEETING', '会议讨论'),
                                                 ('NO', '拒绝')],
                                        verbose_name='市场部决策')
        mkt_priority = models.CharField(max_length=10,
                                        blank=True,
                                        choices=[('', '请选择'), ('H', '高'), ('M', '中'), ('L', '低')],
                                        verbose_name='优先级')
        mkt_comment = models.TextField(blank=True, verbose_name='市场团队建议')
    
        # Conclusion 结论
        # final_decision = models.TextField(blank=True, verbose_name='决策及产品管理团队建议')
    
        # Executor 执行方
        plan = models.DateField(null=True, blank=True, verbose_name='计划发布时间')
        exe_owner = models.CharField(max_length=50,
                                     blank=True,
                                     verbose_name='项目负责人')
        exe_owner_mail = models.EmailField(max_length=100,
                                           blank=True,
                                           verbose_name='邮箱')
        exe_leader_mail = models.EmailField(max_length=100,
                                            blank=True,
                                            verbose_name='经理邮箱')
        cr_number = models.CharField(max_length=200,
                                     blank=True,
                                     verbose_name='CR')
        cn_number = models.CharField(max_length=200,
                                     blank=True,
                                     verbose_name='CN')
        mrd_date = models.DateField(null=True, blank=True, verbose_name='MRD')
        exe_comment = models.CharField(max_length=1000,
                                       blank=True,
                                       null=True,
                                       verbose_name='备注')
    
        invalid_prd = models.CharField(max_length=500,
                                       blank=True,
                                       null=True,
                                       verbose_name='Invalid Products')
        # 添加user, file外键
        user = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL)
        attachments = models.ManyToManyField(FeatureExtensionFile, blank=True)
        status = models.CharField(max_length=100,
                                  blank=True,
                                  null=True,
                                  choices=[('0', '新需求'), ('1', '技术评估'), ('2', '市场评估'), ('3', '评估结论'), ('4', '实施计划')],
                                  verbose_name='状态')
    
        class Meta:
            ordering = ['-id']
    
        def __str__(self):
            return self.title
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91

    序列化器serializer.py

    class OeccDomesticSerializer(ModelSerializer):
        class Meta:
            model = OeccDomestic
            fields = '__all__'
    
    
    class OeccDomesticField(serializers.PrimaryKeyRelatedField):
        def to_representation(self, value):
            if not value:
                return None
            obj = OeccDomestic.objects.get(pk=value.pk)
            if obj:
                data = OeccDomesticSerializer(obj).data
                return data
    
    
    class OeccOverseaSerializer(ModelSerializer):
        class Meta:
            model = OeccOversea
            fields = '__all__'
    
    
    class OeccOverseaField(serializers.PrimaryKeyRelatedField):
        def to_representation(self, value):
            if not value:
                return None
            obj = OeccOversea.objects.get(pk=value.pk)
            if obj:
                data = OeccOverseaSerializer(obj).data
                return data
    
    
    class OeDomesticSerializer(ModelSerializer):
        class Meta:
            model = OeDomestic
            fields = '__all__'
    
    
    class OeDomesticField(serializers.PrimaryKeyRelatedField):
        def to_representation(self, value):
            if not value:
                return None
            obj = OeDomestic.objects.get(pk=value.pk)
            if obj:
                data = OeccOverseaSerializer(obj).data
                return data
    
    
    class OeOverseaSerializer(ModelSerializer):
        class Meta:
            model = OeOversea
            fields = '__all__'
    
    
    class OeOverseaField(serializers.PrimaryKeyRelatedField):
        def to_representation(self, value):
            if not value:
                return None
            obj = OeOversea.objects.get(pk=value.pk)
            if obj:
                data = OeOverseaSerializer(obj).data
                return data
    
    class FeatureExtensionQuerySerializer(ModelSerializer):
        category = serializers.SerializerMethodField()
        solution = serializers.SerializerMethodField()
        complexity = serializers.SerializerMethodField()
        mkt_decision = serializers.SerializerMethodField()
        mkt_priority = serializers.SerializerMethodField()
        status = serializers.SerializerMethodField()
    
     	# 多对多字段序列化
        oecc_domestic = OeccDomesticField(queryset=OeccDomestic.objects.all(), many=True)
        oecc_oversea = OeccOverseaField(queryset=OeccOversea.objects.all(), many=True)
        oe_domestic = OeDomesticField(queryset=OeDomestic.objects.all(), many=True)
        oe_oversea = OeOverseaField(queryset=OeOversea.objects.all(), many=True)
        tech_ss = TechSsFiled(queryset=subsystem.objects.all(), many=True)
        attachments = FeatureExtensionFileField(queryset=FeatureExtensionFile.objects.all(), many=True)
        # 一对多字段序列化
        user = UserField(queryset=User.objects.all())
        
    
        class Meta:
            model = feature_ext
            fields = '__all__'
    
    	# 此处使用钩子函数是为了显示models中的元组可选字段,必须以get开头
        def get_category(self, obj):
            return obj.get_category_display()
    
        def get_solution(self, obj):
            return obj.get_solution_display()
    
        def get_complexity(self, obj):
            return obj.get_complexity_display()
    
        def get_mkt_decision(self, obj):
            return obj.get_mkt_decision_display()
    
        def get_mkt_priority(self, obj):
            return obj.get_mkt_priority_display()
    
        def get_status(self, obj):
            return obj.get_status_display()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104

    视图函数views.py

    class FeatureExtensionListView(APIView):
        def get(self, request):
            pageSize = int(request.GET.get('pageSize', 10))
            pageNumber = int(request.GET.get('pageNumber', 1))
            search_kw = request.GET.get('search_kw', '')
            sortName = request.GET.get('sortName', '')
            sortOrder = request.GET.get('sortOrder', '')
    
            obj_all = feature_ext.objects.all()
            # 查询
            if search_kw:
                obj_all = obj_all.filter(Q(title__icontains=search_kw) | Q(full_name__icontains=search_kw) |
                                         Q(tech_comment__icontains=search_kw) | Q(mkt_comment__icontains=search_kw))
            if sortName == 'no':
                sortName = 'id'
            # 方法一:直接先排序,再获取分页数据
            # if sortOrder == 'desc':
            #     page_obj_list = obj_all.order_by('-{}'.format(sortName))[(pageNumber - 1) * pageSize:(pageNumber) * pageSize]
            # else:
            #     page_obj_list = obj_all.order_by(sortName)[(pageNumber - 1) * pageSize:(pageNumber) * pageSize]
    
            # 方法二:django内置分页工具类
            # 1.先排序
            if sortOrder == 'desc':
                obj_list = obj_all.order_by('-{}'.format(sortName))
            else:
                obj_list = obj_all.order_by(sortName)
            paginator = Paginator(obj_list, per_page=pageSize)
            # 2.再获取指定页码的数据
            page_obj_list = paginator.page(pageNumber)
    
            total = obj_all.count()
            rows = FeatureExtensionQuerySerializer(page_obj_list, many=True).data
            page_data = get_page_all_data(total, rows, sortOrder, pageNumber, pageSize)
            # print(page_data)
            if page_data:
                return JsonResponse(page_data)
            return api_bad_request('数据加载失败!')
            
    def get_page_all_data(total, rows, sortOrder, pageNumber, pageSize):
        for i in range(len(rows)):
            if sortOrder == 'desc':
                no = total - (pageNumber - 1) * pageSize - i
            else:
                no = (pageNumber - 1) * pageSize + i + 1
            rows[i]['no'] = no
        data = {"total": total, "rows": rows}
        return data
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    免责声明:以上内容和代码仅供参考!

  • 相关阅读:
    明明设计的是高带宽,差点加工成开路?
    Hive执行计划之hive依赖及权限查询和常见使用场景
    Linux内核之堆溢出的利用
    内容安全检测接口
    react create-react-app v5 从零搭建项目
    SpringBoot如何自定义启动Banner 以及自定义启动项目控制台输出信息 类似于若依启动大佛 制作教程
    基于ssm的学生综合测评管理系统047
    【100天精通Python】Day63:Python可视化_Matplotlib绘制子图,子图网格布局属性设置等示例+代码
    《MLB棒球创造营》:走近棒球运动·华盛顿国民队
    数据库MySQL的初级基础操作
  • 原文地址:https://blog.csdn.net/qq_43030934/article/details/128003456