You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在DataTable渲染后将Django的payrolled_list填充到Select2下拉框

问题:DataTable触发后无法将Django后端payrolled_list数据填充到Select2下拉框

DataTable渲染或触发后,无法把Django后端返回的payrolled_list数据填充到Select2下拉框中。尝试在drawCallback里编写填充逻辑,但不知道如何正确获取payrolled_list数据,不确定是否必须使用Django模板语法{{payrolled_list}}来实现联动。


核心问题分析

  • 后端返回的payrolled_list是序列化后的JSON字符串,前端未正确解析并提取该数据
  • 当前drawCallback中的payrolledListData是空数组,未从DataTable的AJAX响应中获取有效数据

解决步骤

  1. 修复后端序列化格式:将serialize('json')返回的JSON字符串转为Python列表,确保前端拿到的是可直接使用的数组
  2. 拦截AJAX响应提取数据:利用DataTable的ajax.dataSrc回调,从后端响应中提取payrolled_list并保存
  3. 更新drawCallback逻辑:使用保存的payrolled_list数据填充下拉框,同时正确初始化Select2

修改后的Django后端代码

import json
from django.core.serializers import serialize

# 将序列化的JSON字符串转为Python列表
payrolled_list = json.loads(serialize('json', TevIncoming.objects.filter(status_id=4).order_by('first_name')))

response = {
    'data': data,  # data为表格渲染所需的列表数据
    'payrolled_list': payrolled_list  # 转为数组格式返回给前端
}
return JsonResponse(response)

修改后的DataTable配置代码

const table2 = $('#tbl-box-a');

if ($.fn.DataTable.isDataTable('#tbl-box-a')) {
    table2.DataTable().destroy();
}

// 全局变量保存payrolled_list数据
let payrolledList = [];

dataTable2 = table2.DataTable({
    processing: true,
    serverSide: true,
    ajax: {
        url: "{% url 'employee-dv' %}",
        data: function (d) {
            d.dv_id = dv_no_id;
        },
        dataSrc: function(response) {
            // 从响应中提取payrolled_list并保存
            payrolledList = response.payrolled_list;
            // 返回表格数据给DataTable渲染
            return response.data;
        }
    },
    columns: [
        { data: 'id' },
        { data: 'code' },
        { data: 'account_no' },
        { data: 'id_no' },
        { data: 'name' },
        { data: 'final_amount' },
        { data: 'purpose' },
        { data: 'dv_no', name: 'dv_no' },
        { data: 'multiple_charges' },
        { data: 'total', name: 'total' },
    ],
    columnDefs: [
        {   
            targets: 0,
            render: function(data, type, row, meta) {
                return '<tr data-row-id="' + row.id + '"><td><input type="checkbox"></td></tr>';
            },
        },
        {
            targets: 1,
            render: function(data) {
                return data;
            },
        },
        {
            targets: 2,
            render: function(data) {
                console.log(data);
                return (!data && data !== 0) ? '' : '<span class="badge bg-label-warning">' + data + '</span>';
            },
        },
        {
            targets: 3,
            render: function(data) {
                return '<span class="badge bg-label-primary">' + data + '</span>';
            },
        },
        {
            targets: 5,
            render: function (data) {
                return data;
            },
        },
        {
            targets: 6,
            render: function (data) {
                return '<td><input type="text" class="form-control emp-purpose" value="'+data+'"></td>';
            },
        },
        {
            targets: 7,
            render: function (data) {
                let charges =  '<select class="form-select emp-charges" id="emp-charges">' +
                '<option></option>'+ 
                '{% for row in charges %}'+ 
                '<option value="{{ row.id }}">{{ row.name }}</option>'+ 
                '{% endfor %}'+ 
                '</select>';
                return charges;
            },
        },
        {
            targets: -1,
            title: 'Action',
            orderable: false,
            searchable: false,
            render: function (data, type, row) {
                return '<a class="btn btn-sm btn-icon item-delete" id="' + row.id + '"><i class="text-primary ti ti-trash"></i></a>';
            },
        },
    ],
    dom: '<"card-header flex-column flex-md-row"<"head-label text-center"><"dt-action-buttons text-end pt-3 pt-md-0"B>><"row"<"col-sm-12 col-md-6"l><"col-sm-12 col-md-6 d-flex justify-content-center justify-content-md-end"f>>t<"row"<"col-sm-12 col-md-6"i><"col-sm-12 col-md-6"p>>',
    buttons: [],
    drawCallback: function (settings) {
        const $payrollSelect = $('#payroll-name');
        $payrollSelect.empty();

        // 添加空选项
        $payrollSelect.append('<option></option>');

        // 遍历数据填充下拉框(注意Django序列化后的数据结构:pk为ID,fields包含模型字段)
        payrolledList.forEach(item => {
            $payrollSelect.append(`<option value="${item.pk}">${item.fields.first_name}</option>`);
        });

        // 初始化/更新Select2,先销毁旧实例避免冲突
        if ($payrollSelect.length) {
            if ($payrollSelect.data('select2')) {
                $payrollSelect.select2('destroy');
            }
            $payrollSelect.wrap('<div class="position-relative"></div>');
            $payrollSelect.select2({
                placeholder: 'Choose Employee',
                dropdownParent: $payrollSelect.parent(),
                allowClear: true,
            });
        }
    }
});

内容的提问来源于stack exchange,提问作者Henry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 08:06:04