[DRF] 게시판 프로젝트 댓글 기능 구현하기

mia·2024년 8월 12일
0

DRF 기반으로 게시판 서비스를 만들어보자❗ 4탄

필요한 기능

댓글 관련 기능

  • 댓글 생성
  • 댓글 1개 가져오기/댓글 목록 가져오기
  • 댓글 수정
  • 댓글 삭제
  • 게시글을 가져올 때 댓글도 가져오기

모델

댓글 모델에 필요한 필드는 다음과 같이 정의할 수 있다.

작성자
작성자 프로필
해당 댓글을 작성한 게시글
댓글 내용

댓글은 게시글과 밀접한 연관이 있기에 앱을 따로 만들지 않고, 이미 있는posts/models.py에 추가해 주도록 하자.

class Comment(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
    post = models.ForeignKey(Post, related_name='comments', on_delete=models.CASCADE)
    text = models.TextField()
  • ForeignKey로 User, Profile, Post와 연결되어 있고 댓글 내용인 text만 추가되었다.

마이그레이션한다.


시리얼라이저

댓글 또한 게시글과 마찬가지로 작성할 때와 가져올 때 각각 다른 시리얼라이저가 필요하다.

또, 게시글에서도 댓글을 불러올 수 있어야 한다.
nested serializer 개념을 활용해 댓글 시리얼라이저를 게시글 시리얼라이저에 넣어주면 된다.
이때, 게시글 시리얼라이저에 댓글 시리얼라이저가 포함되다 보니 댓글 시리얼라이저가 더 위에(먼저) 선언되어야 한다.

from rest_framework import serializers

from users.serializers import ProfileSerializer
from .models import Post, Comment

class CommentSerializer(serializers.ModelSerializer):
    profile = ProfileSerializer(read_only=True)

    class Meta:
        model = Comment
        fields = ("pk", "profile", "post", "text")

class CommentCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = ("post", "text")


class PostSerializer(serializers.ModelSerializer):
    profile = ProfileSerializer(read_only=True)
    comments = CommentSerializer(many=True, read_only=True)
    # 댓글 시리얼라이저를 포함하여 댓글 추가

    class Meta:
        model = Post
        fields = ("pk", "profile", "title", "body", "image", "published_date", "likes", "comments")

class PostCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ("title", "category", "body", "image")


Viewset으로 간단히 개발하면 된다.
댓글에 필요한 권한도 게시글과 동일하게, 모두가 댓글을 볼 수 있으나 댓글 작성은 유저만, 댓글 수정/삭제는 해당 댓글 작성자만 가능하도록 한다.

앞서 선언했던 CustomReadOnly 퍼미션을 활용해 posts/views.py에 작성한다.
새로 만든 모델과 시리얼라이저도 추가한다.

class CommentViewSet(viewsets.ModelViewSet):
    queryset = Comment.objects.all()
    permission_classes = [CustomReadOnly]

    def get_serializer_class(self):
        if self.action == 'list' or 'retrieve':
            return CommentSerializer
        return CommentCreateSerializer
    
    def perform_create(self, serializer):
        profile = Profile.objects.get(user=self.request.user)
        serializer.save(author=self.request.user, profile=profile)

URL

라우터를 활용해 간단히 설정할 수 있다.

from django.urls import path
from rest_framework import routers

from .views import PostViewSet, like_post, CommentViewSet

router = routers.SimpleRouter()
router.register('posts', PostViewSet)
router.register('comments', CommentViewSet)

urlpatterns = router.urls + [
    path('like/<int:pk>/', like_post, name='like_post')
]

실행

Insomnia에서 /posts/1/로 GET 요청을 보내보면, comments가 추가된 것이 보인다.

실제로 댓글을 작성하려면, /comments/에 POST 요청을 보내면 된다.
헤더에 토큰을 꼭 넣어주자.

다시 게시글에 GET 요청을 보내보면 댓글이 추가되어 있다.


profile
바보

0개의 댓글

관련 채용 정보