QnA

class PostSerializer(serializers.ModelSerializer):
    # author = serializers.PrimaryKeyRelatedField(read_only=True)

    class Meta:
        model = Post
        fields = (
            'author',
            'created_date',
        )
        read_only_fields = (
            'created_date',
        )
        depth = 1
  • depth=0 이면, pk값만 출력
  • depth=1 이면, author의 모든 값이 출력
  • author 안에 dict가 더 있고 depth=2 이면, 그 값들 까지 출력

단점은 원하는 값을 고를 수가 없다. 그러므로 커스터마이징해서 사용해야 한다.

Nested API

Post에 Author 추가

author 필드의 값이 pk가 아닌, 하나의 Objects(dict)로 나타나도록 수정

1. 관련 테스트 코드 작성
2. 해당 테스트코드가 작동하도록 PostSerializer 수정 및 UserSerializer 작성
3. 테스트 + 포스트맨 작동 확인

post/tests/tests_api.py

def test_post_create(self):
    # ...

    response_author = response.data['author']
    self.assertIn('pk', response_author)
    self.assertIn('username', response_author)

def test_post_list(self):
    # ...

    # 생성된 response의 author 필드가 pk가 아닌 dict 형태로 전달되는지 확인
    # print(response.data)
    for item in response.data:
        # print(item)
        self.assertIn('author', item)
        item_author = item['author']
        # print(item_author)
        self.assertIn('pk', item_author)
        self.assertIn('username', item_author)

member/serializers.py

serializer가 필드를 나타낼수 있다. 참고 링크

from django.contrib.auth import get_user_model
from rest_framework import serializers

User = get_user_model()


class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = (
            'pk',
            'username',
        )

post/serializer/post.py

class PostSerializer(serializers.ModelSerializer):
    author = UserSerializer(read_only=True)

    class Meta:
        model = Post
        fields = (
            'pk',
            'author',
            'created_date',
        )
        read_only_fields = (
            'author',
            'created_date',
        )

Post에 PostPhoto 추가

Post에 연결된 PostPhoto를 리스트 내부의 Objects 형태로 리턴

1. 관련 테스트 코드 작성
2. 해당 테스트코드가 작동하도록 PostSerializer 수정 및 PostPhotoSerializer 작성
3. 테스트 + 포스트맨 작동 확인
4. postphoto_set 이름을 photo_list로 변경

post/tests/tests_api.py

    def test_post_create(self):
        # ...

        # response의 key값 검사
        self.assertIn('author', response.data)
        self.assertIn('created_date', response.data)
        self.assertIn('postphoto_set', response.data)


        # response의 postphoto_set 값 검사
        response_postphoto_set = response.data['postphoto_set']
        self.assertIsInstance(response_postphoto_set, list)
        for postphoto_object in response_postphoto_set:
            self.assertIn('pk', postphoto_object)
            self.assertIn('photo', postphoto_object)
            self.assertIn('created_date', postphoto_object)

post/serializer/post.py

# init 파일의 위치때문에 뒤에 있는 PostPhotoSerializer를 불러오지 못하므로 아래와 같이 설정
from post.serializer.post_photo import PostPhotoSerializer

__all__ = (
    'PostSerializer',
)


class PostSerializer(serializers.ModelSerializer):
    author = UserSerializer(read_only=True)
    postphoto_set = PostPhotoSerializer(many=True, read_only=True)

    class Meta:
        model = Post
        fields = (
            'pk',
            'author',
            'created_date',
            'postphoto_set',
        )
        read_only_fields = (
            'author',
            'created_date',
        )

postphoto_set 이름을 photo_list로 변경

post/serializer/post.py

class PostSerializer(serializers.ModelSerializer):
    author = UserSerializer(read_only=True)
    photo_set = PostPhotoSerializer(source='postphoto_set', many=True, read_only=True)

    class Meta:
        model = Post
        fields = (
            'pk',
            'author',
            'created_date',
            'photo_set',
        )

Pagination

Setting the pagination style

쉽고 간단한 방법이지만, 원하지 않는 곳에서도 페이지네이션이 될 수 있다.

Modifying the pagination style

PageNumberPagination클래스를 오버라이드해서 사용하는 방법

API Reference

1. PageNumberPagination

매개변수에 single number를 page 번호로 받는다.

2. LimitOffsetPagination

여러 데이터베이스 레코드를 검색할 때 사용한다. 이 방법은 limitoffset 파라미터를 받는다.

  • limit : 반환할 최대 항목 수
  • offset : 시작 위치

3. CursorPagination

정방향 및 역방향 컨트롤 만 제공하며, 임의의 위치로 이동할 수 없다. 하지만, 다음과 같은 이점이 있다.

  • 새로운 항목이 추가되도 정상적으로 동작한다.
  • 큰 데이터를 사용도 지원한다.
  • 속도도 느려지지 않는다.
post-list 요청 시, Pagination될 수 있도록 변경
1. 관련 테스트 코드 작성 (가능하면)
2. Pagination 문서 보고 CustomPagination 구현
3. pagination_class에 지정
4. 포스트맨 확인

utils/pagination.py

from rest_framework.pagination import CursorPagination


class PostPagination(CursorPagination):
    page_size = 5
    ordering = '-created_date'

post/apis/post.py

class PostList(generics.ListCreateAPIView):
    # ...
    pagination_class = PostPagination

중간자 모델

1. 팔로우, 차단을 함께 만들 수 있는 중간자 모델 구현
 - 검색 : django follower twitter model
2. MyUser 메서드로 follow, block, friends, following_list, follower_list

과제

  • DRF API Guide 읽기
    • Request ~ Pagination, Exceptions 필수
  • Inst-api 프로젝트
    • 중간자 모델 기능 모두 구현
    • EB를 이용해 서버에 배포