장고

개발일지 16 - 베스트 댓글 만들기

sorecord 2024. 8. 30. 11:25

댓글하고 대댓글의 데이터베이스가 나누어져 있어서 따로 구분을 해서 코드를 구현해야 한다.

 

comment_reply DB에서 값을 좀 더 편하게 가져올 수 있게 함수를 하나 만들었다.

 

def get_all_replies(comment):
    
    all_replies = []
    direct_replies = comment.replies.all()

    
    for reply in direct_replies:
        all_replies.append(reply)   
        all_replies.extend(get_all_replies(reply))
    print(all_replies,'alll')
    return all_replies

 

comment.replies.all()을 호출하여 현재 댓글에 대한 직접적인 대댓글을 가져온다. 

이후 반복문을 통해 반복을 하면서 all_replies에 값을 추가해주고  get_all_replies(reply)를 호출하여 현재 대댓글에 대한 모든 대댓글을 재귀적으로 가져온다.

 

즉, 댓글의 대댓글 대댓글의 대댓글까지 다 가져오는 함수이다.

 

comments_anno = post.comments.annotate(like_count=Count('comment_like_users'))
comment_replies = []
for comment in comments_anno:
    replies = get_all_replies(comment)
    for reply in replies:
        # 각 대댓글에 대해 좋아요 수를 추가
        reply.like_count = reply.commentR_like_users.count()
        comment_replies.append(reply)

 

comments_anno에서 좋아요 수를 계산해 like_count라는 필드를 만들어 저장한다. 

comment_replies도 마찬가지이다.

 

comments_anno = [comment for comment in comments_anno if comment.comment_like_users.count() > 0]
comment_replies = [reply for reply in comment_replies if reply.commentR_like_users.count() > 0]

 

베스트 댓글이 되는 값에 좋아요가 0인 댓글이 있으면 안되기에 0인 댓글을 제외하는 코드를 구현해준다.

 

 comment_replies.sort(key=lambda x: x.commentR_like_users.count(), reverse=True)

    # 댓글과 대댓글을 합쳐서 상위 3개의 항목을 선택
combined = list(chain(comments_anno, comment_replies))
combined.sort(key=lambda x: x.like_count, reverse=True)
best_combined = combined[:3]

comment_replies 리스트를 대댓글의 좋아요 수에 따라 내림차순으로 정렬해준다.

이후 댓글과 대댓글 DB에서 출력한 값을 합쳐준뒤에 다시 재정렬하여 좋아요 수 상위 3개만을 뽑아서 탬플릿으로 전송을 해준다. 

 

 <div class="best-comments">
                <h3>베스트 댓글</h3>
                {% for comment in best_comments %}
                    <div class="best-comment-box">                          
                            <strong>{{ comment.author.nickname }}</strong>: {{ comment.content|truncatechars:50 }}
             
                        <span>좋아요: {{ comment.like_count }}</span>
                    </div>
                {% endfor %}
            </div>

 

위와 같이 코드를 구현을 해주었다. 

 

이렇게 좋아요가 0이 아닐경우 상위 3개의 값만을 가져와서 실시간으로 바뀌는 베스트 댓글을 확인할 수 있다.