본문 바로가기

내배캠/TIL

TIL/35/20230428

728x90

Serializer란?

django의 object, queryset 인스턴스 등 복잡한 테이터들을 json같은 다른 콘텐츠 유형으로 쉽게 변환 할 수 있다.

 

create, update 시 validation 기능을 제공한다.

 

serializer Meta class

- serializer에서 사용되는 설정 파일이다.

- model에 사용 될 테이블을 적어주고, field에 사용될 필드를 적어준다.

- extra_kwargs, read_only_fields와 같은 옵션을 통해 다양한 설정이 가능하다.

 

기본적인 serializer 사용법

- serializers.py

from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
   class Meta:
        # serializer에 사용될 model, field지정
        model = User
        # 모든 필드를 사용하고 싶을 경우 fields = "__all__"로 사용
        fields = ["username", "password", "fullname", "email"]

- views.py

from rest_framework.response import Response
from rest_framework import status

from user.serializers import UserSerializer

def get(self, request):
    user = request.user
    # serializer에 queryset을 인자로 줄 경우 many=True 옵션을 사용해야 한다.
    serialized_user_data = UserSerializer(user).data
    # context= 를 통해 원하는 데이터를 serializer에 넘겨주고, self.context를 사용해 호출 가능하다.
    # serialized_user_data = UserSerializer(user, context={"some_key": "some_value"}).data
    return Response(serialized_user_data, status=status.HTTP_200_OK)

# return data
"""
{
    "username": "user",
    "password": "pbkdf2_sha256$320000$u5YnmKo9luab9csqWpzRsa$pKfqHnBiF5Rgdo1Mj9nxNOdhpAl9AhPVXFPXkbPz7Mg=",
    "fullname": "user's name",
    "email": "user@email.com"
}
"""

외래 키 관계에 있는 테이블이 있을 경우, 해당 테이블의 serializer를 생성해 함께 사용할 수 있다.

- code(serializer.py)

class UserProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserProfile
        fields = "__all__"

class UserSerializer(serializers.ModelSerializer):
    """
    외래 키는 UserProfile에서 User 테이블로 설정되어 있지만
    one to one 필드기 때문에 userprofile이라는 명칭으로 역참조가 가능하다.
    """
    userprofile = UserProfileSerializer()
    class Meta:
        model = User
        fields = ["username", "password", "fullname", "email", "userprofile"]

SerializerMethodField를 활용해 원하는 필드를 추가하고, 더 나아가서 여러 serializer들을 함께 사용할 수 있다.

- code(serializers.py)

class HobbySerializer(serializers.ModelSerializer):
    # serializers.SerializerMethodField()를 사용해 원하는 필드를 생성한다.
    same_hobby_users = serializers.SerializerMethodField()
    def get_same_hobby_users(self, obj):
        user_list = []
        for user_profile in obj.userprofile_set.all():
            user_list.append(user_profile.user.username)

        return user_list

    class Meta:
        model = Hobby
        fields = ["name", "same_hobby_users"]

class UserProfileSerializer(serializers.ModelSerializer):
    # 외래 키 관계로 이어져 있는 필드는 Serializer를 바로 호출할 수 있다.
    hobby = HobbySerializer(many=True)

    class Meta:
        model = UserProfile
        fields = "__all__"

class UserSerializer(serializers.ModelSerializer):
    # One-to-one 관계에서는 fk처럼 사용 가능하다.
    userprofile = UserProfileSerializer()

    class Meta:
        model = User
        fields = ["username", "password", "fullname", "email", "userprofile"]

# views.py
...
class UserView(APIView)
    def get(self, request):
        user = request.user
        return Response(UserSerializer(user).data, status=status.HTTP_200_OK)

# response data
"""
{
    "username": "admin",
    "password": "pbkdf2_sha256$320000$u5YnmKo9luab9csqWpzRsa$pKfqHnBiF5Rgdo1Mj9nxNOdhpAl9AhPVXFPXkbPz7Mg=",
    "fullname": "zxcv",
    "email": "zxv@asd.com",
    "userprofile": {
        "birthday": "2022-06-08",
        "age": 1,
        "introduction": "asdac",
        "hobby": [
            {
                "name": "독서",
                "same_hobby_users": [
                    "user1",
                    "user2",
                    "user3"
                ]
            }
        ]
    }
}
"""
728x90

'내배캠 > TIL' 카테고리의 다른 글

TIL/43/20230510  (0) 2023.05.10
TIL/36/20230501  (0) 2023.05.01
TIL/34/20230427(정리중)  (0) 2023.04.27
TIL/33/20230426(정리중)  (0) 2023.04.26
TIL/32/20230425  (0) 2023.04.25