장고

개발 일지 11 - 댓글 수정, 삭제 기능 추가

sorecord 2024. 8. 25. 12:07

구현을 하기 전에 그림판에 흐름도를 작성을 한 뒤에 코딩을 진행했더니 훨씬 수월했다. 

 

 

간단하게 설명을 하자면 탬플릿에서 수정 버튼을 누른 뒤에 view.py로 넘어가서 댓글의 위치를 알아내고 수정을 한 뒤에 저장까지 해주는 기능이다. save_comment라는 함수를 하나 더 만들까 하다가 만들지 않아도 되었다.

 

{% if comment.author == user %}
                <form method="post" action="{% url 'delete_comment' comment.id %}" style="display:inline;">
                    {% csrf_token %}
                    <button type="submit" onclick="return confirm('정말로 삭제하시겠습니까?');">삭제</button>
                </form>

                <button type="button" onclick="toggleEditForm({{ comment.id }})">수정</button>

                <div id="edit-form-{{ comment.id }}" class="edit-form" style="display: none;">
                    <form method="post" action="{% url 'edit_comment' comment.id %}">
                        {% csrf_token %}
                        <textarea name="content" placeholder="댓글을 수정하세요." rows="2">{{ comment.content }}</textarea>
                        <button type="submit" name="update_submit">수정 완료</button>
                    </form>
                </div>
            {% endif %}
            
function toggleEditForm(commentId) {
            const editForm = document.getElementById(`edit-form-${commentId}`);
            
            // 폼이 보이는 상태인지 숨겨진 상태인지 확인
            if (editForm.style.display === "none" || editForm.style.display === "") {
                editForm.style.display = "block";  // 폼을 보이게 함
            } else {
                editForm.style.display = "none";  // 폼을 숨김
            }
        }

 

위와 같이 코드를 구현해서 댓글을 작성한 작성자의 경우에만 수정, 삭제 버튼을 띄우는 조건문을 만들었다. 밑에는 자바 스크립트 코드이다. 수정 버튼을 눌렀을 때 글을 입력하는 창을 보이게 하고 아닐 경우에는 숨기는 코드이다. 

 

간단한 삭제 버튼부터 살펴보자면 삭제를 눌렀을 때 '정말 삭제하겠습니까?'라는 문구를 팝업창에 띄우고 아래 코드가 실행이 된다. 

 

def delete_comment(request,pk):
    try:
        parent_comment = Comment.objects.get( id=pk) 
        if request.method == 'POST':
            parent_comment.delete()
            return redirect('post_detail',pk=parent_comment.post.id)
    except Comment.DoesNotExist:
        parent_reply = Comment_Reply.objects.get( id=pk) 
        if request.method == 'POST':
            parent_reply.delete()
            try:
                # 우선 comment 필드에서 게시글 ID를 가져옴
                post_id = parent_reply.comment.post.id
            except AttributeError:
                # 만약 comment 필드가 None이면 parent 필드를 통해 게시글 ID를 가져옴
                post_id = parent_reply.parent.comment.post.id
            return redirect('post_detail',pk=post_id)

 

try-except문이 많은데 어제 댓글 기능을 고치지 않았다면 오늘 수정, 삭제 기능을 추가하기는 어려웠을 것이다. 

DB가 나누어져 있는 관계로 처음 Comment에 댓글이 입력이 되어있다면 상관이 없지만 없을 경우에 except문으로 comment_reply DB로 넘어가서 해당 아이디를 찾는 코드이다. 

 

한번더 try-except문이 사용이 되는데 현재 위치를 찾기 위해서 사용했다. 처음 입력하는 댓글은 게시글의 아이디를 찾아서 해당 페이지로 redirect하지만 대댓글의 경우는 comment 필드, 대대댓글 그리고 쭉 이어지는 댓글들은 parent 필드에서 아이디 값을 찾아서 redirect를 시켜주어야 한다.

 

이제 수정 부분 코드를 살펴보자 

 

def edit_comment(request,pk):
    try:
        
        parent_comment = Comment.objects.get( id=pk) 
        if request.method == 'POST':
            new_content = request.POST.get('content')
            parent_comment.content = new_content
            parent_comment.save()
            return redirect('post_detail', pk=parent_comment.post.id)
    except Comment.DoesNotExist:
        parent_reply = Comment_Reply.objects.get( id=pk) 
        if request.method == 'POST':
            new_reply_content = request.POST.get('content')
            parent_reply.content = new_reply_content
            parent_reply.save()
            try:
                # 우선 comment 필드에서 게시글 ID를 가져옴
                post_id = parent_reply.comment.post.id
            except AttributeError:
                # 만약 comment 필드가 None이면 parent 필드를 통해 게시글 ID를 가져옴
                post_id = parent_reply.parent.comment.post.id
            
            return redirect('post_detail',pk=post_id)

 

 

parent_comment에서 내가 수정을 하고자 하는 댓글의 위치를 가져오고 request.POST.get으로 지금 내가 새로 입력한 값을 가져온다. 그 값을 parent_comment.content값에 넣은 뒤 저장을 하면 수정 기능이 완성된다.

 

parent_reply도 마찬가지이다.