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()
마이그레이션한다.
댓글 또한 게시글과 마찬가지로 작성할 때와 가져올 때 각각 다른 시리얼라이저가 필요하다.
또, 게시글에서도 댓글을 불러올 수 있어야 한다.
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)
라우터를 활용해 간단히 설정할 수 있다.
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 요청을 보내보면 댓글이 추가되어 있다.