관계(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 |