유누킴

Django Restframework ModelSerializer 활용 방법 본문

Tech/Django

Django Restframework ModelSerializer 활용 방법

Yunhoo_kim 2017. 12. 7. 18:48
728x90
Django Restframework ModelSerializer 활용 방법

 Django Rest framework DRF에 가장 매력적인 Serializer인 ModelSerializer를 활용하는 방법에 대해서 소개하겠습니다. ModelSerializer는 Django의 Model Instance를 직렬화 할 수 있는 좋은 클래스인데요. 이를 활용하면 더욱더 많은 기능을 사용할 수 있기 때문에 핵심되고 사용하면서 꼭 필요하다고 생각하는 기능들에 대한 소개를 드리겠습니다. 


 1. 다른 ModelSerializer를 Field로 사용하기 

만약 User 테이블이 존재하고 User 테이블을 참조하는 사용자의 경력 정보를 저장하는 Career 테이블이 있다고 가정합니다. 사용자는 UserSerializer에서 User의 테이블 정보만이 아닌 User가 참조된 테이블의 데이터도 가져고오 싶은 경우가 생깁니다. 예를 들면 사용자 프로필 페이지에서 사용자의 테이블에 있는 성, 이름, 프로필 사진 URL과 함께 사용자가 등록한 Career 정보를 보여줘야합니다. 이때 제가 소개하는 기능을 사용하지 않으면, 처음 UserSerializer를 불러오고 그 다음 CareerSerializer의 정보를 불러오고 UserSerializer 데이터에 경력정보를 추가해줘야하는 추가 코딩이 필요할 것입니다. 하지만 여기서 소개 드릴 기능은 외래키로 연결된 테이블의 정보를 field로 불러와 같은 Serializer에 포함할 수 있도록 하는 기능입니다.

 
class UserSerializer(serializers.ModelSerializer):

    career = CareerSerializer(many=True)

    class Meta:
        model = User
        fields = ('id', 'first_name', 'last_name', 'profile_image', 'password', career')
        extra_kwargs = {"password" : {"write_only" : True}}

class CareerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Career
        fields = ('id', 'company')
class UserSerializer(serializers.ModelSerializer):

    career = CareerSerializer(many=True)

    class Meta:
        model = User
        fields = ('id', 'first_name', 'last_name', 'profile_image', 'password', career')
        extra_kwargs = {"password" : {"write_only" : True}}

class CareerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Career
        fields = ('id', 'company')
위 코드와 같이 User, Career 모델이 구성되어 있고, UserSerializer, CareerSerialzer가 구성되어 있다. 프로그래머는 UserSerializer를 통해서 사용자의 경력 정보까지 불러오고 싶은 경우가 있다. 이때 ModelSerializer의 자신이 추가하고자하는 변수명과 UserSerializer 모델과 참조관계에 있는 테이블의 Serializer를 위와 같이 추가하여 사용할 수 있다. career라는 변수안에 CareerSerializer를 사용하여 User의 Career 정보까지 불러오는 ModelSerializer를 구성할 수 있다. 이때 many=True라고 설정된 부분은 User 테이블과 Career 테이블이 OneToOne이 아닌 OneToMany 관계이므로 many=True 설정을 추가하여 사용자의 모든 경력정보를 불러올 수 있도록 한다. 또한 ModelSerializer 내부 Meta Class안에 클래스 변수로 선언된 변수 명을 꼭 포함해야한다. 만약 포함하지 않게되면 Serializer에선 에러가 발생한다. 클래스 변수에는 설정되어있지만, fields 내부에 추가되어 있지않다고 에러를 발생시킨다. 

 2. Meta Class write only 설정 

User 테이블에서는 사용자가 처음 가입시에 패스워드를 입력하지만, 사용자 프로필페이지에서는 패스워드 데이터를 보여주면 절대 안된다. 그렇기 때문에 ModelSerialzer에서는 extra_kwargs 내부에 write_only 설정을 추가하여서 해당 데이터를 직렬화시 포함시키지 않을 수 있다. 

 3. MethodSerializerField 사용하기 

 프로필 페이지에서 사용자의 평점 혹은 사용자에게 남기 리뷰의 개수등 연산이 필요한 정보를 추가해야하는 경우가 있다. 위의 테이블 정보를 보면 사용자 이름이 first_name last_name이 나뉘어 있지만 데이터를 조회할때에는 full_name이라는 필드로 사용자 성과 이름을 한번에 포함시키고 싶을 수도 있다. 이때 사용할 수 있는 기능은 MethodSerializerField이다. MethodSerializerField는 커스터마이징 필드를 생성할 수 있는 기능이다. custom_field 라는 필드를 추가하고 해당 field에 대한 정보는 클래스 내부의 get_필드명() 함수로 구현하면 ModelSerializer에서 자동으로 필드와 함수를 매핑하여 같이 직렬화 할 수 있다. 예를 보면

 

class UserSerializer(serializers.ModelSerializer):

    career = CareerSerializer(many=True)
    full_name =	serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = ('id', 'first_name','last_name','profile_name', 'password', 'career')
        extra_kwargs = {"password" : {"write_only" : True}}

    def get_full_name(self,obj):
	return "%s %s" % (obj.first_name, obj.last_name)


UserSerializer 내부에 full_name = serializer.SerializerMethodField()가 추가되었고 내부 함수로 get_full_name함수를 추가한다.

get_filed_name함수의 인자는 2개 self와 obj이다.

이때 obj는 해당 Serializer에서 설정한 모델의 인스턴스이다.


예를 들면

user = User.objects.get(id=1) # id가 1인 유저
U_ser = UserSerializer(user)
u_ser.data

라고 했을때 obj는 id 가 1인 유저 인스턴스이다.



해당 기능을 사용해서 조금 더 자신에게 맞는 커스터마이징된 ModelSerializer를 구성할 수 있다.


이 글은 작성자가 공부하고 개발하며 느낀점을 토대로 작성한 글입니다. 여러분의 지적과 질문은 감사히 받겠습니다.

읽어주셔서 감사합니다..!






'Tech > Django' 카테고리의 다른 글

DRF(Django Rest framework) 소개  (0) 2017.12.06
Django urls.py 설정 방법  (0) 2017.12.05
Django란  (0) 2017.12.04