DRF(Django Rest Framework)(10) _ 댓글 CRUD
01. 댓글 모델 생성하기
- 댓글 기능을 사용하기 위한 모델은 아래와 같이 생성해주었다.
# articles/models.py
class Comment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
article = models.ForeignKey(Article, on_delete=models.CASCADE)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return str(self.content)
- 위에서 정의한 모델에서는 article이라는 필드를 ForeignKey로 가져오고 있다. 이 때 역참조를 위해 사용하는 related_name이 따로 지정이 되어있지 않지만, 아래와 같이 "comment_set"이라는 이름이 기본적으로 추가되어있어 작성하지 않아도 사용이 가능하다.
# articles/models.py
class Comment(models.Model):
...
article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name="comment_set")
...
02. urls.py 수정하기(article_id 넣어주기)
- 기존에 url에는 article_id를 url에 넣어주지 않았기 때문에, 아래와 같이 수정해주었다.
# articles/urls.py
from django.urls import path
from articles import views
urlpatterns = [
path('', views.ArticleView.as_view(), name='article_view'),
path('<int:article_id>/', views.ArticleDetailView.as_view(), name='article_detail_view'),
path('<int:article_id>/comment/', views.CommentView.as_view(), name='comment_view'),
path('<int:article_id>/comment/<int:comment_id>/', views.CommentDetailView.as_view(), name='comment_detail_view'),
path('<int:article_id>/like/', views.LikeView.as_view(), name='like_view'),
]
03. 댓글 가져오기
- 댓글 기능에 사용할 serializer도 아래와 같이 추가해주었다.
# articles/serializers.py
from .models import Article, Comment
...
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = '__all__'
- 이제 댓글기능에 사용할 CommentView를 아래와 같이 작성하였다.
# articles/views.py
from .serializers import ArticleListSerializer, ArticleSerializer, ArticleCreateSerializer, CommentSerializer
...
class CommentView(APIView):
def get(self, request, article_id):
article = Article.objects.get(id=article_id)
comments = article.comment_set.all()
serializer = CommentSerializer(comments, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
- 포스트 맨에서 작성된 댓글을 잘 가져오고 있는지 확인할 수 있다.
04. 댓글 생성하기
- 댓글 생성기능을 구현하기 위해 Serializer를 아래처럼 하나 더 추가해준다.
- 필요한 필드는 content만 가져온다. 이 때 필드가 하나만 들어갈 경우 트레일링 콤마를 꼭 뒤에 붙여주어야 String으로 인식하지 않으니 주의해야 한다.
# articles/serializers.py
class CommentCreateSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = ('content',)
- CommentView에 댓글 생성을 위한 post라는 함수를 정의해준다. 대부분 구성은 게시글의 post와 유사하지만, CommentCreateSerializer를 사용하는 점, Serializer를 저장할 때 article_id를 사용하는 점을 유의해준다.
# articles/views.py
...
class CommentView(APIView):
...
def post(self, request, article_id):
serializer = CommentCreateSerializer(data=request.data)
if serializer.is_valid():
serializer.save(user=request.user, article_id=article_id)
return Response(serializer.data, status.HTTP_200_OK)
else:
return Response(serializer.errors, stutus=status.HTTP_400_BAD_REQUEST)
- 포스트맨으로 검증하기 위해 comments create라는 request를 만들어준다. 이 때 꼭 Headers에 Authorization 키를 아래와 같이 먼저 추가해주어야 한다. 그렇지 않으면 "Comment.user" must be a "User" instance. 라는 에러를 만나게 된다.
- 댓글을 작성하고 Send 하면 아래와 같이 잘 동작되는 것을 확인할 수 있다.
05. 댓글 수정하기
- 댓글 수정기능을 구현하기도 게시글 수정과 거의 동일하다. 기존 article로 되어있는 변수명들을 comment로 변경해서 불러와 기능을 구현해준다.
# articles/views.py
...
class CommentDetailView(APIView):
def put(self, request, article_id, comment_id):
comment = get_object_or_404(Comment, id=comment_id)
if request.user == comment.user:
serializer = CommentCreateSerializer(comment, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
else:
return Response("권한이 없습니다!", status=status.HTTP_403_FORBIDDEN)
- 포스트맨에서 comment update 리퀘스트를 put형식으로 잡아주고, 아래와 같이 Headers 셋팅을 해준다.
- 그 다음 Send하면 수정한 내용이 잘 반영되는 것을 확인할 수 있다.
06. 댓글 삭제하기
- 댓글 삭제 기능도 마찬가지로 게시글 삭제하기 기능의 일부를 아래와 같이 수정해주었다.
# articles/views.py
...
class CommentDetailView(APIView):
...
def delete(self, request, article_id, comment_id):
comment = get_object_or_404(Comment, id=comment_id)
if request.user == comment.user:
comment.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
else:
return Response("권한이 없습니다!", status=status.HTTP_403_FORBIDDEN)
- 포스트맨으로 확인해보면 204 No content가 확인된다. comment request로 확인해보아도 잘 삭제되어있는 것을 확인할 수 있다.
'DEV > Web 개발' 카테고리의 다른 글
Web 개발 :: 파이썬 Django Rest Framework(11) _ 좋아요, 팔로우 기능 (1) | 2022.11.04 |
---|---|
Web 개발 :: Django rest framework, 추천 시스템, 코사인 유사도, TF-IDF _TIL#44 (0) | 2022.11.04 |
Web 개발 :: Django rest framework, csv to json_TIL#43 (0) | 2022.11.03 |
Web 개발 :: 노래 추천 서비스 프로젝트 SA (0) | 2022.11.02 |
Web 개발 :: 파이썬 Django Rest Framework(9) _ 게시글 상세, 수정, 삭제 (0) | 2022.11.02 |
댓글