Django/DRF

DRF 댓글 대댓글 모델 정의, Post와 serializer 연동

Jong_seoung 2024. 3. 21. 11:31
반응형

댓글,대댓글 모델 정의

# models.py
class Comment(TimeStampedModel, models.Model):
    post = models.ForeignKey('Post', related_name='comments', on_delete=models.CASCADE)
    user = models.ForeignKey(User, related_name='comments', on_delete=models.CASCADE)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    root = models.ForeignKey('self', related_name='root_comment', on_delete=models.CASCADE, null=True, blank=True)

    def __str__(self):
        return '{} : {}'.format(self.author, self.cotent)

    class Meta:
        ordering = ['-created_at']

root는 대댓글을 위해서 만들어둔 필드이다. 추후serializers 사용한다.

 

 

serializers 만들기

# serializers.py

class CommentSerializer(serializers.ModelSerializer):
    root_comment = serializers.SerializerMethodField()
    user = serializers.ReadOnlyField(source='user.nickname')  

    class Meta:
        model = Comment
        fields = ['id', 'post', 'user', 'content', 'created_at', 'root_comment']
    
    def get_root_comment(self, instance):
        serializer = self.__class__(instance.root_comment, many=True)
        serializer.bind('', self)
        return serializer.data

user의 경우 jwt를 이용하여 유저 정보를 가지고 오기 때문에 readonly 값으로 넣어주었다.

root_comment를 이용하여 대댓글이 있을 경우 대댓글을 볼 수 있다.

 

ViewSet

from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework import viewsets

from recipes.permissions import IsOwnerOrReadOnly
from .serializers import CommentSerializer
from accounts.functions import get_user_id


from .models import Comments

class CommentViewSet(viewsets.ModelViewSet):
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]
    queryset = Comments.objects.all()
    serializer_class = CommentSerializer

    def perform_create(self, serializer):
        serializer.save(user=get_user_id(self.request))

get_user_id의 경우 jwt 토큰을 이용하여 user instance를 리턴해주는 함수이다.

 

 

urls.py

from django.urls import path, include
from .viewsets import CommentViewSet
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register('', CommentViewSet, basename='comment')
urlpatterns =[
    path('', include(router.urls)),
]

 

 

PostSerializer에서 Comment 추가

다른분들이 진행한 코드를 보면 아래 접은글처럼 구현을 했는데, API를 날려보니 댓글이 Post에 표시가 되지 않아서 내 입맛대로 변경하였다.

더보기
# 다른분이 진행한 내용

class PostSerializer(serializers.ModelSerializer):
    comments = CommentSerializer(many=True, read_only=True)

    class Meta:
        model = Post
        fields = ('title', 'content', 'comments')
# 내 코드

class PostSerializer(serializers.ModelSerializer):
    comments = serializers.SerializerMethodField()

    class Meta:
        model = Post
        fields = ('title', 'content', 'comments')
        
    def get_comments(self, data):
        comment = Comments.objects.filter(recipe=data.id)
        serializer = CommentSerializer(comment, many=True)
        return serializer.data

 

 

출처

 

[D.R.F] 게시판 댓글 기능 구현하기 - 1:N 관계

안녕하세요 ( ͡• ͜ʖ ͡• ) ! 오늘은 Django RESTful API로 댓글 기능을 구현해보도록 하겠습니다. 댓글을 구현하기 위해서는 우선 댓글을 달 수 있는 모델이 존재해야 합니다. 이 부분은 이전 포스팅

wisdom-990629.tistory.com

 

[Django] RestFramework Serializer 댓글 모델 추가하기

내가 쓴 글이 있으면 밑에 댓글 기능을 추가 하고싶은 요구사항이 생기는 것은 당연하다. Comment 자체를 새로운 App 으로 만들어서 구현한 예제도 있는 듯 하나 Post 모델과 Comment 모델을 하나의 app

freekim.tistory.com

 

반응형