본문 바로가기
파이썬 웹 개발

[Django] datatable Server-side processing _ 10,000row 넘어갈 때 방법

by 배추잠자리 2022. 4. 12.
반응형

datatable 라이브러리는 페이징, 검색, 정렬 등 편하게 활용할 수 있어서 많이들 사용하는 것 같습니다.

하지만 데이터가 10000건이 넘어가면 속도 저하의 문제가 있어요.

대부분은 백단에서 데이터 전체를 받아와서 프론트단에서 조립을 하는 방식으로 데이터테이블을 사용하기 때문에 그렇습니다.

 

이를 해결하기 위해 Server-side processing 방식이 있습니다.

페이지 로드에 필요한 만큼만 ajax로 받아와서 데이터테이블에 뿌려주는 방식이에요.

 

소스코드는 Python Django 기반으로 되어있고, 

사실 로직을 대충 보면 이 소스를 보고도 자바에서도 어렵지 않게 처리할 수 있을거에요.

데이터테이블에 필요한 값만 잘 넘겨주면 되기때문에,,,

 

■ HTML 코드

<div class="">
    <table class="" id="exampleTable">
        <thead class="">
            <tr class="">
                <th>
                    선택
                </th>
                <th>
                    이름
                </th>
                <th>
                    성별
                </th>
                <th>
                    나이
                </th>
                <th>
                    직업
                </th>
            </tr>
        </thead>
    </table>
</div>

 

단순히 <thead> 까지만 작성해주면 됩니다.

<tbody> 부분은 자바스크립트 단에서 처리해줄거에요.

 

 

 

■ 데이터 테이블 생성하는 자바스크립트 

데이터 테이블 생성 소스코드

 

var table_ajax;
function ajax_table() {
    table_ajax = $("#exampleTable").DataTable({
        "serverSide": true,
        "processing": true,
        "searching": false,
        "destroy": true,
        "ordering": false,
        "ajax": {
            "url": '{% url 'api:datatable-ajax' %}',  // 데이터 가져올 url
            "type": "POST",
            "dataSrc": function (res) {
                var data = res.data;
                return data;
            }
        },
        "columns": [
            {"data": "id"},    // 백단에서 넘겨받은 컬럼명
            {"data": "Name"},   // 백단에서 넘겨받은 컬럼명
            {"data": "Gender"},   // 백단에서 넘겨받은 컬럼명
            {"data": "Age"},    // 백단에서 넘겨받은 컬럼명
            {"data": "job"},    // 백단에서 넘겨받은 컬럼명
        ]
    });
}

 

 

ajax 부분에서 url에는 데이터를 가져올 URL을 작성해주면 됩니다.

 

 

 

■ 데이터를 넘겨주는 백단 메소드

 

@csrf_exempt
def data_table_ajax(request):

    draw = int(request.POST.get('draw'))
    start = int(request.POST.get('start'))
    length = int(request.POST.get('length'))
    # print(draw)  순차
    # print(start)  첫번째 레코드 값
    # print(length)  그려질 레코드 수

    _data = Account.objects.filter().values().all().order_by('-pk')

    _count = len(_data)  # 게시글 수
    total = int(_count)  # 게시글 수
    result_data = _data[int(start):int(length+start)]
	
    # result_data에 _data[시작:끝] 페이지 로드에 필요한 개수만 입력됩니다.
    
    return_data = {
        'data': result_data,
        'draw': draw,
        'recordsTotal': total,
        'recordsFiltered': total,
    }
    return JsonResponse(return_data)

 

 

여기까지는 Server-side processing 기본방식입니다.

 

좀만 더 응용을 해보자면, 검색기능에 필요한 데이터를 넘겨줘야 하는 경우

또는 체크박스를 만들어줘야하는 경우를 알려드릴게요.

 

테스트 데이터라 1~2건이지만, 10000row가 넘어도 잘 작동합니다.

 

■ 결과

결과 데이터테이블

 

 

 

■ 데이터 테이블 -> 데이터 전달 및 체크박스 만들기

 

var table_ajax;
function ajax_table() {
    table_ajax = $("#exampleTable").DataTable({
        "serverSide": true,
        "processing": true,
        "searching": false,
        "destroy": true,
        "ordering": false,
        "ajax": {
            "url": '{% url 'api:datatable-ajax' %}',
            "type": "POST",
            "data": {
                'search_test': $('#test').val(),  // 값 전달 가능
            },   // ajax의 데이터 옵션을 통해 데이터를 전달해줄 수 있습니다.
            "dataSrc": function (res) {
                var data = res.data;
                return data;
            }
        },
        "columns": [
            {"data": "id"},
            {"data": "Name"},
            {"data": "Gender"},
            {"data": "Age"},
            {"data": "job"},
        ],
        "columnDefs": [
            {   // 컬럼 순서에 따라 이런식으로 조립을 할 수 있어요.
                "targets": [0],
                "render": function (data, type, full, meta) {
                    return '<input data-member="member_chk" style="zoom:1.5;" type="checkbox" class="' + data + '" name="member_id[]" value="' + data + '" >';
                }
            },
        ],
        "select": {
            "selector": 'td:first-child'
        },
    });
}

 

 

ajax의 data옵션에 데이터를 담아 전달도 가능합니다.

또한 첫번째 컬럼에 columnDefs 옵션을 통해 체크박스 등 다양한 값을 return 할 수 있어요.

 

"targets": [0],
"render": function (data, type, full, meta) {
         return '값';
}

 

# 여기서 "targets"은 컬럼 순서 

"render"에서 data는 값이고,  full을 사용하면 다른 컬럼값을 가져올 수 있어요.

예를 들어  full.Age 를 하면 첫번째 컬럼에서도 나이값을 가져올 수 있습니다.

 

 

체크박스 만들기 결과

데이터테이블 체크박스

 

 

검색어를 넘겨줘서 검색을 하는 경우에는 데이터테이블 생성 객체를 담아뒀던 table_ajax 변수를 destroy() 해주면서 해야되요.

즉 table_ajax.destory() 후  ajax_table()을 실행해주면 됩니다.

 

 

설명이 좀 복잡했는데 어려운 부분이 있따면 언제든지 댓글 남겨주세요~

반응형

댓글