본문 바로가기

Django

[Django] 댓글, 대댓글, 페이지네이션 구현하기

제가 [원티드 X 위코드] 프리온보딩 코스에 참여하면서, 댓글 대댓글 , 페이지네이션 기능을 구현해볼 기회가 생겼어요.

 

기능 구현하면서 배웠던 부분들을 정리해보려고 합니다!

 

시작할게요 :)

 


▶ 구현해야 할 기능

- 댓글 & 대댓글

- 댓글과 대댓글 모두 페이지네이션 적용

 

▶ 폴더 구조

V users(사용자등록)와 posts(게시글 CRUD) 앱을 구성

V decorators.py 는 users 앱안에 구성

V core 앱에는 Timestamp 처럼 공통적으로 쓰이는 기능들을 넣었어요!

├── README.md
├── config
├── core 
├── manage.py
├── mongodb
├── requirements.txt
├── posts
└── users

 

▶ 모델링 / models.py 

posts app > models.py

class Comment(TimeStamp):
    user = models.ForeignKey('users.User', on_delete=CASCADE)
    post = models.ForeignKey('Post', on_delete=models.CASCADE)
    parent_comment = models.ForeignKey('self', on_delete=models.CASCADE, null=True)
    content = models.TextField()

    class Meta:
        db_table = 'comments'

 

V 대댓글을 구현하기 위해 parent_comment 라는 필드를 생성

V parent_comment 필드에는 self 를 사용하여 자기자신을  참조

 

V parent_comment = 0 이면 댓글

V parent_comment = * 이면 * 번 댓글의 대댓글

 

▶ views.py

V 로그인 데코레이터 함수를 사용하여 로그인한 유저만 댓글,대댓글을 작성, 조회 가능하도록 한다.

 

V 'parent_id' 라는 변수에 0이 입력되면 댓글을 조회

V 'parent_id' 라는 변수에 *이 입력되면 *번 댓글의 대댓글을 조회

→ parent_id 가 0일 때와 그렇지 않을 때를 나누어 filter 조건을 걸어 all_comments 를 다르게 정해줬어요!

 

V URL

{server_url}/posts/1/comments?parent_id=1&offset=0&limit=5

→  1번 게시물 / 1번 댓글의 대댓글을 조회 / 5개의 대댓글을 조회

 

V Pagination

→ limit 은 보여줄 댓글의 갯수

→ offset 은 보여줄 페이지의 수 ex) offset = 0 이면 0~10까지 댓글 / offset = 1 → 10~20까지 댓글

class CommentView(View):
    @login_decorator
    def get(self, request, post_id):
        parent_id = int(request.GET.get("parent_id","0"))

        if parent_id == 0:
            all_comments = Comment.objects.filter(post_id=post_id, parent_comment__isnull=True).select_related('user')
        
        else:
            all_comments = Comment.objects.filter(post_id=post_id, parent_comment_id=parent_id).select_related('user')

        limit = int(request.GET.get("limit","10"))
        offset = int(request.GET.get("offset","0"))
        offset=offset*limit
        
        comments  = all_comments[offset:offset+limit]

        comment_list = [{   
                'comment_id' : comment.id,
                'user_id'    : comment.user_id,
                'email'      : comment.user.email,
                'content'    : comment.content,
                'created_at' : comment.created_at,
                'updated_at' : comment.updated_at,
                'parent_id'  : comment.parent_comment_id,
                } for comment in comments
            ]
        return JsonResponse({'comments':comment_list}, status=200)

'Django' 카테고리의 다른 글

[Django] 구글로 이메일 보내기  (0) 2021.10.21
[Django] 유닛테스트  (0) 2021.09.16