2019.05.18 jquery & ajax를 활용하여 댓글 구현하기입니다.

  • 패스트캠퍼스 웹 프로그래밍 스쿨 수업 정리 내용

목표

  • 댓글을 달 때 ajax가 작동하여 새롭게 페이지가 리로드 되지 않게 하기
  • ajax를 통해 단 댓글을 해당 DB에 저장하고
  • 그 댓글만을 가지고와서 댓글창의 가장 상단에 끼워넣기

로직

  • 먼저 해당 댓글 입렴 폼의 태그를 확인한다.
  • 그리고 그 폼의 submit을 눌렀을 때 해당 변화가 없도록 막고
    • submit의 경우 return false를 활용한다.
  • url을 지정하고 serialize를 통해 현재 폼에 담겨져 있는 값들을 가지고 온다.
  • ajax를 통해 url이 작동하도록 하고 해당 url을 views로 연결하여
  • 해당 views.py(댓글 구현 뷰)에서 처리할 수 있도록 한다.
  • 해당 뷰에서 처리 이후에 해당 채워넣을 부분의 html을 반환해줄 수 있도록 comment_single.html을 구현한다.
  • 그리고 뷰에서 그 html파일을 JsonResponse를 통해 반환해준다.
  • 다시 해당 템플릿에서 .done 부분에 prepend(가장 상단에 넣어주기)를 통해 해당 파일을 넣는다.

1. 해당 댓글 입력폼의 태그 확인하기

<form action="{ % url "board:comment" object.id % }" method="POST" id="comment_form">
{ % csrf_token % }
<input type="hidden" name="is_ajax" value="">
    {{comment_form.as_p}}
    <input type="submit" value="Comment" class="btn btn-outline-primary">

</form>

<table class="table table-striped" id="comment_list">
    <tbody>
    { % for comment in comments % }
   <tr>
        <td>{{ comment.text }}</td>
        <td>{{ comment.author.username}}</td>
        <td>{{ comment.created }}</td>
        <td><a href="{ % url 'board:comment_delete' comment.id % }">삭제하기</a></td>
        <td><a href="{ % url 'board:comment_update' comment.id % }">수정하기</a></td>
    </tr>
    { % endfor % }
    </tbody>
</table>

2. 그 폼의 submit을 눌렀을 때 해당 변화가 없도록 막는다.

{ % block extra_script % }
<script type="text/javascript">
    $(function () {
        $('#comment_form').submit(function(e){
            alert('댓글쓰기 완료');
            return false;   //이게 없으면 다시 리로드 되서 다녀온다.
        });
    });

</script>
{ % endblock % }

3. url을 지정하고 serialize를 통해 현재 폼에 담겨져 있는 값들을 가지고 온다.

  • url의 경우 기존에 연결되어 있는 url을 활용한다.
  • serialize를 통해 현재 폼에 담겨져 있는 값들을 가지고 온다.

4. views.py 완성하기

def comment(request, document_id):
    is_ajax = request.POST.get('is_ajax')

    document = get_object_or_404(Document, pk=document_id)

    comment_form = CommentForm(request.POST)
    comment_form.instance.author_id = request.user.id
    comment_form.instance.document_id = document_id
    if comment_form.is_valid():
        comment = comment_form.save()

    if is_ajax:
        html = render_to_string('board/comment/comment_single.html',
                                {'comment':comment})
        return JsonResponse({'html':html})

    return redirect(document)
  • is_ajax를 POST를 통해 is_ajax를 받는다. html의 jquery가 제대로 작동했다면 1을 가지고 있다.
  • 해당 새롭게 생긴 댓글을 넣어주기 위한 간단한 html을 새롭게 제작한다.
    • 만약 is_ajax가 있다면 html은 single.html을 rendering하고 위에 comment와 함께 넘겨줄 수 있도록 한다.
    • JsonResponse를 통해 html을 넘겨준다.

comment/comment_single.html

    <tr class="comment_row">
        <td class="comment_text">{{ comment.text }}</td>
        <td>{{ comment.author.username}}</td>
        <td>{{ comment.created }}</td>
        <td><a href="{ % url 'board:comment_delete' comment.id % }" class="btn_comment_delete">삭제하기</a></td>
        <td><a href="{ % url 'board:comment_update' comment.id % }" class="btn_comment_update">수정하기</a></td>
    </tr>
  • 해당 페이지를 통해 가장 위에 끼워 넣을 댓글을 만들어낸다.

5. jquery 완성하기


{ % block extra_script % }
<script type="text/javascript">
    $(function () {
        $('#comment_form').submit(function(e){
            $('input[name="is_ajax"]').val("1")
            // alert('댓글쓰기 완료');
            url = $(this).attr('action'); //원래 다녀와야하는 url
            params = $(this).serialize(); //현재 폼에 담겨있는 값들을 가지고 올 수 있게 해준다.
            $.ajax({
                url:url,
                method : "POST",
                data: params,

            }).done(function(data){
                $('#id_text').val("");
                $('#comment_list tbody').prepend(data.html); //tbody 시작지점에 요소 끼워넣기
                //$('comment_list tbody').append(tr); //tbody 끝 지점에 요소 끼워넣기
                // is_ajax 값 초기화
                $('input[name="is_ajax"]').val("");
            });

            return false;   //이게 없으면 다시 리로드 되서 다녀온다.
        });
</script>
{ % endblock % }
  • 해석하기
    • comment_form이라는 id를 가진 곳에서 submit을 누르면 막는다.(e, return false)
    • is_ajax라는 이름에 1의 값을 부여해준다.
    • url은 원래 이동하는 url로 설정한다.
    • params는 serialize()를 통해 현재 폼에 담겨 있는 값들을 가지고 올 수 있게 한다.
    • ajax를 url 요청이 위에 정의해놓은 url로 왔을 때 그리고 method는 POST방식으로 왔을 때 작동한다.
    • data는 params를 받는다.
    • 위의 ajax를 통해 URLConf를 통해 views.py를 다녀오고 JsonResponse를 통해 해당 데이터를 반환 받는다.
    • params도 views.py를 통해 data : params로 넣어서 보내준다.
    • 야는 왜 id_text 값을 어디에서도 설정해주지 않았는데 적었던 데이터가 사라지는 것일까?
      • 폼 형태로 끼워넣으면 알아서 id_text가 설정된다.

댓글달기 전체 과정보기

  • submit이 일어나면 is_ajax를 1로 바꾼다.
  • url 은 댓글남기기 페이지 주소를 가지고 온다.
  • params = serialize를 통해 폼에 있는 데이터들을 하나로 붙인다.
  • 리 다이렉션이 안되고 데이터를 추가로 가지고 오고 싶퍼서 is_ajax를 설정한 것이다.
  • 뷰에서 is_ajax이 있으면 return Jsonresponse를 하고
  • 아니면 redirect를 하도록 한다.

+ Recent posts