11월 16일 원티드 프리온보딩 백엔드 21일차 TIL
in Wantedpreonbording on Wantedpreonbording, Django, Drf, Pagination
1️⃣ 진행상황
- Serializer, View 생성 및 URL 연결
2️⃣ 진행상황리뷰
# audio/utils/audio_converter.py
...
class ProjectCreateSerializer(serializers.ModelSerializer):
...
def create(self, validated_data: dict[str, str]):
title = validated_data.get("project_title")
project = Project.objects.create(project_title=title)
text = validated_data.get("text")
sentences = separate_text_by_sentence(text)
for index, sentence_text in enumerate(sentences):
sentence, is_created = Sentence.objects.get_or_create(text=sentence_text)
if is_created:
create_audio_file(sentence_text)
Audio.objects.create(
project_id=project,
index=index,
sentence=sentence,
)
return project
class AudioSerializer(serializers.ModelSerializer):
...
def update(self, instance, validated_data):
instance.speed = validated_data.get("speed")
if instance.text != validated_data.get("text"):
sentence, is_created = Sentence.objects.get_or_create(
text=validated_data.get("text")
)
instance.sentences = sentence
if is_created:
create_audio_file(validated_data.get("text"), speed=instance.speed)
instance.save()
return instance
ProjectCreateSerializer
로Project
를 생성할 때,text
를 받아서 문장 단위로 분리하고,Sentence
가 존재하는지 확인하고, 존재하지 않는다면create_audio_file
을 통해 음성 파일을 생성. 이후 생성한Sentence
와Project
를 연결하여Audio
를 생성.AudioSerializer
로Audio
를 수정할 때,text
가 변경되었다면Sentence
를 생성하고,create_audio_file
을 통해 음성 파일을 생성. 이후Audio
의speed
를 변경하고 저장.
# audio/views.py
from rest_framework.pagination import PageNumberPagination
...
class AudioPagination(PageNumberPagination):
page_size = 10
...
class ProjectView(APIView):
def get(self, request: Request, project_pk: int) -> Response:
"""
GET /api/v1/project/<project_pk>/
Get project from pk.
"""
project = get_object_or_404(Project, pk=project_pk)
audio = project.audio_set.all().order_by("index")
# paginate
paginator = AudioPagination()
result_page = paginator.paginate_queryset(audio, request)
return paginator.get_paginated_response(
AudioSerializer(result_page, many=True).data
)
AudioPagination
을 통해page_size
를 10으로 설정.Project
의pk
를 받아서Audio
를index
순으로 정렬하여 반환하는ProjectView
를 생성.
3️⃣ Today I Learned
Pagination
데이터를 여러 페이지에 나눠 보여주는 기능이다.
DRF에서는 rest_framework.pagination
에서 제공하는 PageNumberPagination
을 그대로 사용하거나, 상속받아 원하는 대로 변경하여 사용할 수 있다.
config.settings.py
에서 DEFAULT_PAGINATION_CLASS
를 설정하여 전역으로 사용할 수 있다.
# config.settings.py
...
REST_FRAMEWORK = {
...
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10,
}
ViewSet
에서 pagination_class
를 설정하여 해당 ViewSet
에서만 사용할 수 있다.
# audio/views.py
...
class AudioViewSet(viewsets.ModelViewSet):
...
pagination_class = AudioPagination
APIView
에서는 좀더 설정이 필요하다.
APIView
에서 pagination_class
를 설정하고, paginate_queryset
를 통해 queryset
을 paginator
에 넘겨주고, get_paginated_response
를 통해 Response
를 반환한다.
내 경우는 커스텀이 필요해서 다음과 같은 방식을 사용했다.
# audio/views.py
...
class ProjectView(APIView):
def get(self, request: Request, project_pk: int) -> Response:
...
paginator = AudioPagination()
result_page = paginator.paginate_queryset(audio, request)
return paginator.get_paginated_response(
AudioSerializer(result_page, many=True).data
)