일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 |
- db
- vitepwa
- Django
- Javascript
- 플로이드워셜
- PWA
- 데코레이터
- VITE
- 셀프넘버
- pwa적용하기
- git
- TypeScript
- 싸피셜
- queryset
- 리액트
- sqld
- SQL
- 알고리즘
- unionfind
- 머신러닝종류
- 백준
- 싸피10기
- SSAFYcial
- 14658
- Python
- react
- QuerySetAPI
- SSAFY
- 싸피
- js
- Today
- Total
Meme's IT
[Django] DRF(2) N:1 Relation 본문
이번엔 게시판에 댓글다는 기능으로 DRF를 N:1 관계에서 어떻게 쓰는지 확인해보자
0. Serialize를 위해 SerializerModel만들어주기
# articles/serializers.py
from .models import Article, Comment
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = '__all__'
1. GET - 모든 댓글 조회
(1) urls.py에서 url부터 추가해주기
# articles/views.py
urlpatterns = [
...
path('comments/', views.comment_list), # 추가
]
(2) view 함수 작성
# articles/views.py
from .models import Article, Comment
from .serializers import ArticleListSerializer, ArticleSerializer, CommentSerializer
@api_view(['GET'])
def comment_list(request):
comments = Comment.objects.all()
serializer = CommentSerializer(comments, many=True) # 다중데이터 → many=True
return Response(serializer.data)
(3) POSTMAN으로 확인하기
- http://127.0.0.1:8000/api/v1/comments/으로 확인
- GET방식으로 바꿔주기
2. GET - 단일 댓글 조회
(1) 단일 댓글이므로 url부터 다시 만들기
# article/urls.py
urlpatterns = [
...
path('comments/<int:comment_pk>/', views.comment_detail),
]
(2) view함수 작성
@api_view(['GET'])
def comment_detail(request,comment_pk):
comment = Comment.objects.get(pk=comment_pk)
serializer = CommentSerializer(comment)
return Response(serializer.data)
(3) POSTMAN확인
- http://127.0.0.1:8000/api/v1/comments/1/
- GET 방식으로
3. POST - 단일 댓글 생성
(1) 단일 댓글도 article의 화면 → 댓글 생성이므로 새로운 url이 필요
urlpatterns = [
...
path('article/<int:article_pk>/comments/',views.comment_create),
]
(2) view함수 작성
@api_view(['POST'])
def comment_create(request,article_pk):
article = Article.objects.get(pk=article_pk)
serializer = CommentSerializer(data=request.data)
if serializer.is_valid(raise_exception=True): # 예외가 발생되는것을 바로 처리해줌
serializer.save(article=article) # 위에서 가져온 article
return Response(serializer.data, status=status.HTTP_201_CREATED)
(3) POSTMAN으로 확인하기
- http://127.0.0.1:8000/api/v1/article/1/comments/ 으로 확인
- body에 내용 넣어주기 / POST 방식으로
- 근데 오류가 난다, 왜? valid검사하고 나서 → article 정보를 넣어주므로 valid 검사에서 걸리기 때문
- 그럼 어떻게 해야 valid검사할 대는 빼고 나중에 넣어줄 수 있을까?
- 이런 옵션을 '읽기 전용 필드'라고 한다
- 읽기 전용 필드: ①유효성 검사에서 제외시키고 ②데이터 조회 시에는 출력 하는 필드
# articles/serializers.py
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = '__all__'
read_only_fields = ('article',) # 읽기전용필드 추가
4. DELETE & PUT - 단일 댓글 삭제 및 수정
두 기능은 굳이 url추가할 필요 없음 → 댓글 삭제 페이지에서 동시에 가능
(1) 바로 view함수 수정
@api_view(['GET', 'DELETE', 'PUT'])
def comment_detail(request,comment_pk):
comment = Comment.objects.get(pk=comment_pk)
if request.method == 'GET':
serializer = CommentSerializer(comment)
return Response(serializer.data)
elif request.method == 'DELETE':
comment.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
elif request.method == 'PUT':
serializer = CommentSerializer(comment,data=request.data) # partial필요 없음
if serializer.is_valid(raise_exception=True):
serializer.save()
return Response(serializer.data)
(2) POSTMAN으로 확인
- http://127.0.0.1:8000/api/v1/comments/20/
- DELETE
- http://127.0.0.1:8000/api/v1/comments/19/
- POST방식, 수정할 데이터 입력
근데 여기서 댓글 조회할 때, article의 정보가 pk로 온다
확인하기 힘들지 않을까?
게시글의 제목까지 제공하도록 하고 싶을 땐?
# 응답 데이터 재구성
# articles/serializers.py
class CommentSerializer(serializers.ModelSerializer):
# Override 진행
# 근데, 제목만 있는게 없네 → 새로 만들자
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = ('title',)
article = ArticleSerializer(read_only=True) # 읽기 전용 필드를 여기로 이사
class Meta:
model = Comment
fields = '__all__'
# read_only_fields = ('article',)
POSTMAN으로 제목이 조회되는 것을 확인할 수 있다.
# 역참조 데이터 구성
댓글 → 게시글을 조회할 때는 comment.article으로 조회할 수 있는데
게시글 → 댓글일 때는 어떻게 해야할까?
modelform을 사용할 때에는 article.comment_set으로 가능했었다
json에서는 역참조를 어떻게 해야할까?
- 단일 게시글 조회시 해달 게시글에 작성된 댓글 목록 데이터 붙여서 응답
- 단일 게시글 조회시 해당 게시글에 작성된 댓글 갯수 데이터도 함께 붙여서 응답
1. 단일 게시글 + 댓글 목록 출력
# articles/serializers.py
class ArticleSerializer(serializers.ModelSerializer):
comment_set = CommentSerializer(many=True, read_only=True)
# 다중데이터 - many=True, 읽기전용 - read_only=True
class Meta:
model = Article
fields = '__all__'
이때, CommentSerializer를 가져오는 것이므로 CommentSerializer를 더 위쪽에 있도록 해야함
article에도 comment가 같이 나오는걸 확인할 수 있다
2. 단일 게시글 + 댓글 개수
댓글을 세어주는 필드가 새로 필요함
class ArticleSerializer(serializers.ModelSerializer):
comment_set = CommentSerializer(many=True, read_only=True)
# 새롭게 추가
comment_count = serializers.IntegerField(source='comment_set.count', read_only=True)
class Meta:
model = Article
fields = '__all__'
comment_count가 생긴 것을 확인할 수 있다.
▶ source
- 필드를 채우는 데에 사용할 속성의 이름
- 점 표기법을 사용하여 속성을 탐색할 수 있음
▶주의사항
- 특정 필드를 override하면 read_only_fields는 동작하지 않음
- 해당 필드의 read_only 키워드 인자로 작성해야 함
'BackEnd > Django' 카테고리의 다른 글
[Django] API KEY 숨기는 방법 (0) | 2023.10.27 |
---|---|
[Django] API 문서화 (0) | 2023.10.19 |
[Django] DRF(1) single model (0) | 2023.10.18 |
[Django] DRF란? (0) | 2023.10.18 |
[Django] RESTful API (2) 자원의 행위 / 표현 (0) | 2023.10.18 |