장고 - Table에서 checkbox 데이터를 ajax로 전달하기

  • 이번 포스트에서는 테이블에서 checkbox type으로 선택된 특정 열의 데이터를 ajax를 이용하여 서버에 전달하고,
  • 서버에서 보낸 data를 받아오는 방법에 대해 학습한 것을 정리하였다.

Table에서 특정 열의 data를 서버에 ajax로 전달하는 방법

1. 테이블에 저장할 데이터를 모델에 작성

  • 경로 : program(앱) > models.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Program(models.Model):
    name = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="program_name") # R 데이터 분석
    time = models.CharField(max_length=100) # 19:00 ~ 24:00
    teacher = models.CharField(max_length=20) # 박지웅
    place = models.CharField(max_length=50) # 2호선 성수역 부근 패스캠퍼스 B강의장
    enroll = models.ManyToManyField(get_user_model(), related_name="enrolled_program", blank=True)

    def __str__(self):
    return self.teacher

2. 화면에 보여질 페이지 작성

  • 경로 : program > views.py

    1
    2
    3
    def program_list(request):
    programs = Program.objects.all()
    return render(request, 'program/program_list.html', {'object_list':programs})
  • 경로 : program > templates > program > program_list.html

    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
    {% block content %}
    <form action="{% url 'category:program_submit' %}" method="post" id="program_form" style="margin:20px 0 15px 0">
    <!-- form으로 데이터 전달 시, 반드시 {% csrf_token %} 입력 -->
    {% csrf_token %}
    <table style="width:100%; height:400px; margin-bottom:20px; border-top:solid; border-bottom:solid">
    <tr>
    <td>프로그램</td>
    <td>기간</td>
    <td>시간</td>
    <td>강사</td>
    <td>장소</td>
    <td>선택</td>
    </tr>
    {% for object in object_list %}
    <tr>
    <td>{{object.name}}</td>
    <td>19.06.01 ~ 19.08.31</td>
    <td>{{object.time}}</td>
    <td>{{object.teacher}}</td>
    <td>{{object.place}}</td>
    <td><input type="checkbox" class="programChecked" value="{{object.id}}" name="{{object.name}}"></td>
    </tr>
    {% endfor %}
    </table>
    <input type="submit" style="float:right" class="btn btn-outline btn-primary pull-right" id="selectBtn" value="신청하기">
    </form>
    {% endblock %}

3. 선택한 테이블 열의 데이터를 ajax를 이용하여 서버에 전달

  • 경로 : prgram > templates > program > program_list.html
    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
    {% block extra_script %}
    <script type="text/javascript">
    $(function(){
    $('#program_form').submit(function(e){
    <!-- preventDefault로 페이지 이동 못하도록 설정 -->
    e.preventDefault();

    <!-- 데이터 전달할 열의 데이터의 id를 저장할 리스트 초기화 설정 -->
    var obj_id_list = new Array();

    <!-- checkbox 체크된 열의 데이터를 순차적으로 obj_id_list에 push -->
    $('input[class=programChecked]:checked').each(function() {
    obj_id_list.push($(this).val());
    });
    <!-- form의 action=""에 있는 경로를 url이라는 변수로 저장 -->
    url = $(this).attr('action');
    <!-- ajax로 데이터 전달 시, 데이터가 리스트 타입일 때 아래 코드 작성 -->
    jQuery.ajaxSettings.traditional = true;
    <!-- ajax로 특정 데이터의 id를 해당 서버에 전달 -->
    $.ajax({
    url: url,
    method: 'POST',
    data: {
    <!-- 리스트 형태로 보낼 때는 변수 뒤에 '[]' 입력 -->
    'obj_id_list[]' : obj_id_list,
    <!-- form 데이터 보낼 때, 아래 코드 입력 필수 -->
    'csrfmiddlewaretoken':'{{csrf_token}}',
    <!-- 서버쪽에서 ajax 요청이 왔는지 확인하기 위해, is_ajax를 True로 전달 -->
    'is_ajax':true,
    },
    <!-- 서버쪽으로 데이터 전달 및 수신 성공 시, html 단에서 실행할 코드 입력 -->
    }).done(function(data){
    <!-- 서버로부터 json 형태로 'works'를 데이터로 전달받을 때 -->
    if(data.works){
    alert('신청 완료되었습니다.');
    var move = confirm('결제 페이지로 이동하겠습니까?')
    if(move == true){
    <!-- 사용자가 결제페이지 이동 희망 시, 특정 url 경로로 이동 -->
    window.location.href = '{% url 'category:my_page' %}';
    }
    <!-- 사용자가 결제페이지 이동 미희망 시, 해당 페이지 새로고침 -->
    else{
    location.reload();
    }
    }
    });
    return false;
    });
    });
    </script>
    {% endblock %}

4. 서버에서 ajax로 전달받은 데이터 처리

  • 경로 : program > views.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    def program_submit(request):
    # ajax로 요청했는지 확인하기 위해, is_ajax가 true인지 확인
    is_ajax = request.POST.get('is_ajax')
    program_list = Program.objects.all()
    # ajax 요청 확인 시,
    if is_ajax:
    # ajax로 전달받은 데이터를 원하는 변수명으로 저장
    obj_id_list = request.POST.getlist('obj_id_list[]')
    user = request.user

    # 데이터를 요청한 user를 program의 enroll 필드에 저장
    for obj_id in obj_id_list:
    program = Program.objects.get(pk=int(obj_id))
    user = request.user
    # user를 enroll 필드로 설정한 모든 program 객체를 user_program 변수로 저장
    user_program = user.enrolled_program.all()
    # user_program 객체 중, 요청받은 데이터의 id가 있는 객체를 user_program 변수로 저장
    user_program = user_program.filter(id=int(obj_id))
    # user_program이 존재한다면, program의 enroll 필드에 해당 user 추가
    if not user_program.exists():
    program.enroll.add(user)
    # 데이터를 요청한 페이지에 {'works':True}라는 json 데이터 전달
    return JsonResponse({'works':True})