📘 DRF
목차
- 역참조 데이터 추가하기
- 커스텀 필드 추가하기
- 응답 구조만 변경하기
- 상속 활용하기
🤪 Serializer 활용하기
Serializer를 여러 가지 상황에 맞춰서 활용하는 방법을 알아봅시다!
1. 역참조 데이터 추가하기
👩🏻💼 동료 개발자 :
저희, Article 상세 조회하면 화면에서 댓글도 같이 보여야 해서요.
지금은 콜을 두 번해야 하는데, 콜을 하나로 묶어주실래요?
→ 우리가 할 일
{ "id": 1, "title": "제목제목제목", "content": "내용내용내용", "created_at": "2023-12-28T08:02:08.364474Z", "updated_at": "2024-04-06T08:01:00.260880Z", "comments" : { // 여기에 여러가지 코멘트가 함께 들어가면 좋을 것 같은데🤔 } }
Article에 Comment 추가하기
- Nested Relationships
- Serializer는 기존 필드를 override 하거나 추가적인 필드를 구성할 수 있다.
- 이때 모델 사이에 참조 관계가 있다면 해당 필드를 포함하거나 중첩할 수 있다.
- Serializer는 기존 필드를 override 하거나 추가적인 필드를 구성할 수 있다.
- 결국 우리가 조작해줘야할 것은~~ Serializer!
- 현재 Article → Comments 접근이 필요 == 역참조
- 역참조 시 사용할 수 있는 comment_set이 있으나 우리는 "comments"로 명명했다.(매니저 이름)
💡 아하!
"comments"라는 매니저 이름으로 된 필드를 다시 override 하는데, 표현 방식은 CommentSerializer를 사용하는구나.
# 모든 comments들을 CommentSerializer에 넘겨서 직렬화한 후, fields 추가해 줘! comments = CommentSerializer(many=True, read_only=True) # 오버라이딩
↓ 해보자
articles/serializers.py
더보기
⬇️
from rest_framework import serializers
from .models import Article, Comment
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = "__all__"
read_only_fields = ("article",)
class ArticleSerializer(serializers.ModelSerializer):
# 모든 comments들을 CommentSerializer에 넘겨서 직렬화한 후, fields 추가해 줘!
comments = CommentSerializer(many=True, read_only=True) # 오버라이딩
class Meta:
model = Article
fields = "__all__"
- CommentSerializer와 ArticleSerializer의 코드 위치를 바꿔주었어요
- ArticleSerializer에 comments 코드를 추가해주었어요
# 모든 comments들을 CommentSerializer에 넘겨서 직렬화한 후, fields 추가해 줘!
comments = CommentSerializer(many=True, read_only=True) # 오버라이딩
코드 한 줄을 추가했을 뿐인데,
한 번에 댓글까지 조회할 수 있게 됐어요!
2. 커스텀 필드 추가하기
👩🏻💼 동료 개발자 :
저희 화면에 보면 댓글 수도 함께 표시가 되고 있어서요, 물론 데이터 받아와서 제가 카운트해도 되긴 하는데,
데이터 내려주실 때 한 번에 주실 수 있을까요?
댓글 수 필드 추가하기
- "comments"의 경우 우리의 Django가 자동으로 추가해 주는 매니저이기에 바로 사용할 수 있었다.
- 하지만 comments_count는 직접 필드를 추가해주는 것이 필요하다.
- source 속성을 이용하여 데이터 값을 전달하는 것 가능하다.
- 우리의 경우 Queryset API 중 하나인 count()를 이용하여 전달해주면 된다!
- source
- SerializerField의 속성으로 해당 필드를 채우는 데 사용하는 속성을 지정한다.
- 점 표기법을 이용하여 내부 속성에 접근할 수 있다. (.count)
💡 아하!
# 댓글 갯수 comments_count = serializers.IntegerField(source="comments.count", read_only=True) #.count가 ORM 함수
↓ 해보자
articles/serializer.py
더보기
⬇️
from rest_framework import serializers
from .models import Article, Comment
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = "__all__"
read_only_fields = ("article",)
class ArticleSerializer(serializers.ModelSerializer):
# 모든 comments들을 CommentSerializer에 넘겨서 직렬화한 후, fields 추가해 줘!
comments = CommentSerializer(many=True, read_only=True) # 오버라이딩
# 댓글 갯수
comments_count = serializers.IntegerField(source="comments.count", read_only=True) #.count가 ORM 함수
class Meta:
model = Article
fields = "__all__"
- comments_count 코드를 추가했어요
# 댓글 갯수
comments_count = serializers.IntegerField(source="comments.count", read_only=True)
#.count가 ORM 함수
이외 많이 찾는 Fields
더보기
Serializer Method Fields
https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield
SerializerMethodField()
from django.contrib.auth.models import User
from django.utils.timezone import now
from rest_framework import serializers
class UserSerializer(serializers.ModelSerializer):
days_since_joined = serializers.SerializerMethodField()
class Meta:
model = User
fields = '__all__'
def get_days_since_joined(self, obj):
return (now() - obj.date_joined).days
get_days_since_joined 가 붙은 필드명의 함수가 실행되어 필드로 추가된다.
3. 응답 구조만 변경하기
👩🏻💼 동료 개발자 :
아래와 같은 댓글 조회에서 article로 내려오는 필드 삭제 부탁드릴게요. 오히려 헷갈려서요.
[ { "id": 22, "content": "수정댓글", "created_at": "1972-09-02T22:34:52.315416Z", "updated_at": "2024-04-06T12:07:29.461800Z", "article": 1 }, { "id": 23, "content": "Try four often third side purpose. Detail require break believe arrive. Wonder avoid out network director.", "created_at": "2018-01-01T10:48:02.905154Z", "updated_at": "2017-04-27T18:30:10.763704Z", "article": 1 },
Custom fields 🔗
- to_representation()
- Serialization 이후 보이는 결과에 대해 자동으로 내부적으로 불리는 함수다.
- 이 메서드를 override 하여 커스텀 형식으로 변경 가능하다.
💡 아하!
class CommentSerializer(serializers.ModelSerializer): # article 삭제(pop) def to_representation(self, instance): ret = super().to_representation(instance) ret.pop("article") return ret
↓ 해보자
articles/serializers.py
더보기
⬇️
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = "__all__"
read_only_fields = ("article",)
# 댓글 목록에서 article 없애기
def to_representation(self, instance):
ret = super().to_representation(instance)
ret.pop("article")
return ret
- def to_representation을 추가했어요
# 댓글 목록에서 article 없애기
def to_representation(self, instance):
ret = super().to_representation(instance)
ret.pop("article")
return ret
article이 없어졌어요!
4. 상속 활용하기
👩🏻💼 동료 개발자 :
죄송한데, 지금 게시글 목록 조회에서도 댓글 관련 필드들이 내려오고 있는데, 이건 상세 조회에서만 나오게 해 주세요.
💡 아하!
class ArticleDetailSerializer(ArticleSerializer):
class를 분리해서 사용하자!
↓ 해보자
1. articles/serializers.py
더보기
⬇️
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = "__all__"
class ArticleDetailSerializer(ArticleSerializer):
# 모든 comments들을 CommentSerializer에 넘겨서 직렬화한 후, fields 추가해 줘!
comments = CommentSerializer(many=True, read_only=True) # 오버라이딩
# 댓글 갯수
comments_count = serializers.IntegerField(source="comments.count", read_only=True)
#.count가 ORM 함수
article의 detail에서만 댓글과 댓글 수를 볼 수 있게끔 새로운 Serializer를 추가해 줬어요!
2. articles/views.py
더보기
⬇️
상세 목록에서만 댓글을 보고 싶기 때문에, Detail 부분만 다 수정해 주었어요
ArticleSerializer에서 ArticleDetailSerializer로 바꾸었어요
그러면 이제, 목록에선 댓글들이 보이지 않아요!
상세에서는 보여요!
'공부 > DRF 공부' 카테고리의 다른 글
[DRF] Django ORM 한 걸음 더, Q(), F(), annotate(), aggregate() (0) | 2025.02.03 |
---|---|
[DRF] Token Auth with JWT, 접근 제한 및 접근하기 (0) | 2025.02.02 |
[DRF] Relationship과 DRF, 댓글 생성 (0) | 2025.01.30 |
[DRF] DRF CBV(Class Based View) 사용하기 (0) | 2025.01.30 |
[DRF] DRF Single Model CRUD (0) | 2025.01.30 |