∟ Framework/∟ DRF

DRF models with relationship CRUD API 구현

최 수빈 2025. 3. 30. 02:17

 

관계(Relationship)가 있는 모델 처리

 

관계가 있는 모델을 직렬화(Serialization)하고 API를 통해 CRUD 기능 구현

Article - Comment 관계

 

 

댓글 기능에 필요한 API

  • 특정 게시글의 모든 댓글 조회 (GET /articles/<article_id>comments/)
  • 특정 게시글에 댓글 작성 (POST /articles/<article_id>comments/)
  • 특정 댓글 삭제 (DELETE /articles/comments/<comment_id>/)
  • 특정 댓글 수정 (PATCH /articles/comments/<comment_id>/)

 

 

모델 정의

# articles/models.py

class Comment(models.Model):
    article = models.ForeignKey(
        Article, on_delete=models.CASCADE, related_name="comments"
    )
    content = models.CharField(max_length=200)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

ForeignKey를 통해 Article과의 관계 설정

related_name="comments":article.comments로 접근 가능

 

 

시리얼라이저 정의

# articles/serializers.py

class CommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = "__all__"
        read_only_fields = ("article",)

read_only_fields: 클라이언트가 직접 입력할 수 없는 필드 처리 (POST 요청 시 불필요한 필드를 제외하고 유효성 검사 통과에 유리)

 

 

Seeding (샘플 데이터 생성)

python manage.py seed articles --number=20 # 20개의 랜덤한 Article 생성
python manage.py seed articles --number=20 --seeder "Comment.article_id" 2 # article_id가 2인 Article에 Comment 20개 생성

 

 

댓글 목록 조회 & 생성 API

# articles/views.py

class CommentListAPIView(APIView):
    def get(self, request, pk):
        article = get_object_or_404(Article, pk=pk)
        comments = article.comments.all()
        serializer = CommentSerializer(comments, many=True)
        return Response(serializer.data)

    def post(self, request, pk):
        article = get_object_or_404(Article, pk=pk)
        serializer = CommentSerializer(data=request.data)
        if serializer.is_valid(raise_exception=True):
            serializer.save(article=article)
            return Response(serializer.data, status=status.HTTP_201_CREATED)

save() 호출 시 serializer.save(article=article)처럼 추가 데이터를 넘길 수 있음

# articles/urls.py

from django.urls import path
from . import views

app_name = "articles"

urlpatterns = [
    path("<int:pk>/comments/", views.CommentListAPIView.as_view(), name="comment_list"),
]

댓글 생성 시 article은 URL에서 가져오고, POST body에는 content만 있으면 됨

 

댓글조회
댓글생성

 

 

 

댓글 삭제/수정 API

# articles/views.py

class CommentDetailAPIView(APIView):
    def get_object(self, comment_pk):
        return get_object_or_404(Comment, pk=comment_pk)

    def delete(self, request, comment_pk):
        comment = self.get_object(comment_pk)
        comment.delete()
        return Response({"pk": f"{comment_pk} is deleted."}, status=status.HTTP_200_OK)

    def patch(self, request, comment_pk):
        comment = self.get_object(comment_pk)
        serializer = CommentSerializer(comment, data=request.data, partial=True)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response(serializer.data)
# articles/urls.py

path("comments/<int:comment_pk>/", views.CommentDetailAPIView.as_view(), name="comment_detail"),

 

댓글삭제
댓글수정

 

'∟ Framework > ∟ DRF' 카테고리의 다른 글

Token Auth with JWT  (0) 2025.03.30
DRF Serializer 활용  (1) 2025.03.30
Class Based View (CBV)  (0) 2025.03.29
DRF Single Model CRUD API 구현  (0) 2025.03.29
Django REST Framework(DRF) API 구현  (0) 2025.03.29