Django 연습

16. Django 대댓글 기능 구현

수달1234 2025. 4. 1. 17:07

📢 시작 🏷️

오늘은 Django를 사용하여서 게시판이나 블로그와 같은 커뮤니티 사이트에서 대댓글 시스템을 구현하는 방법을 알아보겠습니다. 대댓글 기능은 사용자간의 토론 및 대화를 더욱 활발하고 집중이 가능하도록하며, 특정 댓글에 직접 응답할 수 있게하여 사용자 개선에 중요한 기능입니다.

 

📝 모델 정의

class Comment(models.Model):
    """댓글 모델"""
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="comments")
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)    
    
    # 대댓글 기능
    parent = models.ForeignKey('self', null=True,blank=True, on_delete=models.CASCADE, related_name='replies')
    
    def __str__(self):
        return f"{self.author} - {self.post.title[:10]}"
    
    @property
    def children(self):
        """해당 댓글의 대댓글 가져오기"""
        return Comment.objects.filter(parent=self).order_by('created_at')
    
    @property
    def is_parent(self):
        """부모 댓글인지 확인"""
        return self.parent is None

✔️ parent 필드 : 자기 자신을 참조(self)하는 외래키로, 부모댓글을 가리킵니다.

✔️children 메서드 : 해당 댓글의 대댓글 목록을 가져옵니다.

✔️ is_parent 메서드 : 해당 댓글이 부모댓글(원댓글)인지 여부를 반환합니다.

 

 

📝 폼 추가

class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ['content']
        widgets = {
            'content': forms.Textarea(attrs={'class': 'form-control', 'rows': 2, 'placeholder': '댓글을 입력하세요'}),
        }

이제 대댓글 기능을 추가하면서 폼을 새로 구현해야합니다.

 

🔍 views.py

def post_detail(request, post_id):
    """게시글 상세 페이지 + 좋아요/싫어요 개수 포함"""
    post = get_object_or_404(Post, id=post_id)
    comments = post.comments.filter(parent=None)  # 부모 댓글만 가져오기
    comment_form = CommentForm()  # 댓글 폼 추가
    """기존 코드"""

✔️ post_detail 에서는 parent=None(원댓글)인 댓글만 가져오도록 합니다.

 

@login_required
def add_comment(request, post_id):
    """
    댓글 추가 기능
    - parent_id가 있으면 대댓글 추가
    - 없으면 일반 댓글 추가
    """
    post = get_object_or_404(Post, id=post_id)
    parent_id = request.POST.get('parent_id')

    if request.method == "POST":
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.post = post
            comment.author = request.user
            
            # 대댓글인 경우 부모 댓글 설정
            if parent_id:
                parent_comment = get_object_or_404(Comment, id=parent_id)
                comment.parent = parent_comment
            
            comment.save()
            messages.success(request, "댓글이 등록되었습니다.")  # 피드백 추가
    
    return redirect("post_detail", post_id=post.id)

✔️ parent_id 가 있는 경우 대댓글로 처리하도록 합니다.