카테고리 없음

개발 일지 7 - 댓글 기능 수정

sorecord 2024. 8. 21. 14:47

어제 무한히 반복되게 적어야 했던 부분을 수정을 했다.

어떤 식으로 반복이 되고 있는지 간단히 정리한 그림

 

 <ul class="comments-list">
                {% for comment in post.comments.all %}
                     {% include 'book/comment_template.html' with comment=comment %}
                {% endfor %}
            </ul>

 

반복이 계속 될 수 있게끔 새로운 파일하나를 만들어주었다.

 

어떻게 똑같이 반복되는 부분을 간단하게 만들어야 할지 고민을 하다가 각 댓글에 대해 동일한 탬플릿을 재귀적으로 호출하는 코드를 짜주었다. 

 

<li>
    <strong>{{ comment.author.nickname }}</strong> {{ comment.content }}
    <span>{{ comment.created_at|date:"Y-m-d H:i" }}</span>
    <span>좋아요: {{ comment.likes }}</span>
    <button onclick="likeComment({{ comment.id }})">좋아요</button>

    {% if user in user_check %}
        <button onclick="toggleReplyForm({{ comment.id }}, true )">대댓글</button>
        <div id="reply-form-{{ comment.id }}" style="display: none;">
            <form method="post" action="{% url 'save_comment' post.pk %}">
                {% csrf_token %}
                <textarea name="content" placeholder="대댓글을 입력하세요." rows="2"></textarea>
                <input type="hidden" name="parent_id" value="{{ comment.id }}">
                <input type="hidden" name="parent_reply_id" value="{{ comment.id }}">
                <button type="submit" name="reply_submit">대댓글 작성</button>
            </form>
        </div>
    {% endif %}

    <ul class="replies-list" style="margin-left: 20px;">
        {% for reply in comment.replies.all %}
            {% include 'book/comment_template.html' with comment=reply %}
        {% endfor %}
    </ul>
</li>

 

 

이렇게 구현을 해주면 댓글의 댓글 대댓글의 댓글 무한히 이어질 수 있게 만들 수 있다. 

 

view.py에 save_comment함수도 수정을 해주었다. 

 

def save_comment(request, pk):  # 댓글 저장
    post = get_object_or_404(Post_information, pk=pk)
    user_id = request.session.get('username')

    if request.method == 'POST':
        if 'comment_submit' in request.POST:
            # 일반 댓글 처리
            comment_form = CommentForm(request.POST)
            if comment_form.is_valid():
                new_comment = comment_form.save(commit=False)
                new_comment.author = User_information.objects.get(username=user_id)
                new_comment.post = post
                new_comment.save()
                return redirect('post_detail', pk=pk)
            else:
                print(comment_form.errors)

        elif 'reply_submit' in request.POST:
            # 대댓글 처리
            print("대댓글")
            reply_form = CommentReplyForm(request.POST)
            if reply_form.is_valid():
                new_reply = reply_form.save(commit=False)
                new_reply.author = User_information.objects.get(username=user_id)
                print(request.POST)
                print(request)
                # 부모 댓글 또는 대댓글 ID 가져오기
                parent_comment_id = request.POST.get('parent_id')
                count=Comment.objects.all().count()
                if int(parent_comment_id) <= count:
                    parent_comment = get_object_or_404(Comment, id=parent_comment_id)
                    new_reply.comment = parent_comment
                else:
                    # 대댓글의 대댓글 처리
                    parent_reply_id = request.POST.get('parent_reply_id')
                    if parent_reply_id:
                        parent_reply = get_object_or_404(Comment_Reply, id=parent_reply_id)
                        new_reply.parent = parent_reply

                new_reply.save()
                return redirect('post_detail', pk=pk)

    return redirect('post_detail', pk=pk)

 

 

어제도 댓글하고 댓글의 댓글까지는 문제없이 구현할 수 있었다. 오늘 해결해야 하는 문제는 대댓글의 댓글이었다. 

 

위에 반복이 되는 탬플릿에서 parent_id와 parent_reply_id의 값을 가지고 왔다. 그리고 그 값이 comment DB에 있는 값의 개수보다 작거나 같으면 댓글에 댓글을 달 수 있는 것이다. 

 

그렇지 않을 경우는 parent_reply_id을 이용해서 comment_reply DB의 값을 가져온 뒤 자기자신을 부모로 하는 댓글에 또 댓글을 달아 줄 수 있었다. 

 

원래는 comment_reply DB에 comment부분이 comment DB와 외래키로 연결이 되어있었는데 어제 사용을 했던 while문을 그대로 사용을 하니까 총 댓글이 2개가 달리는 문제가 발생했다. 

 

그림으로 간단히 설명하자면 아래와 같다. 

 

 

그래서 comment_reply DB의 값을 null=True로 받고 blank=True로 받을 수 있게끔 변경을 해주었다. 

이렇게 했더니 내가 가지고 있던 문제들을 해결할 수 있었다.