내일배움캠프 - DRF 5일차 개발일지

Dongwoo Kim·2022년 6월 21일
0

내일배움캠프 - DRF

목록 보기
8/12

스파르타 코딩클럽

내일배움캠프 AI 웹개발자양성과정 2회차

DRF 5일차 개발일지

0. 강의요약

  • Q를 사용한 or filter 이해
  • serializer validate, create, update 기능에 대한 이해
  • serializer custom 기능에 대한 이해

1. Q를 사용한 or filter 이해

: qeury를 직접 만들 수 있다.

from django.db.models.query_utils import Q

class UserView(APIView)
    def get(self, request):
        # 취미 중 산책이 있거나 나이가 19살보다 많고 김씨인 사람만 필터 사람만 필터
        query = Q(hobby__name="산책") | Q(age__gt=19, user__name__startswith="김")

        # 취미 중 산책이 있으면서 나이가 19살보다 많은 사람만 필터
        query = Q(hobby__name="산책") & Q(age__gt=19)				
        user_profile_list = UserProfileModel.objects.filter(query)

2. serializer validate, create, update 기능에 대한 이해

1) validator

# data : 입력 데이터
serializer = Serializer(data=data)
serializer.is_valid()

: 입력받은 data가 db에 저장될 수 있는 data로서 유효한지 검사

# user/views.py
class UserView(APIView):
	# 회원 생성
    def post(self, request):
        user_serializer = UserSerializer(data=request.data)
        # serializer validator를 통과하지 않을 경우 .is_valid()가 False로 return된다.
        if user_serializer.is_valid():
            # validator를 통과했을 경우 데이터 저장
        	...

2) creator

# data : 입력 데이터
serializer = Serializer(data=data)
serializer.save()

입력 받은 데이터를 저장

# user/views.py
class UserView(APIView):
	# 회원 생성
    def post(self, request):
        user_serializer = UserSerializer(data=request.data)
        # serializer validator를 통과하지 않을 경우 .is_valid()가 False로 return된다.
        if user_serializer.is_valid():
            # validator를 통과했을 경우 데이터 저장
        	user_serializer.save()
            return Response({"message": "정상"}, status=status.HTTP_200_OK)
        
        return Response(user_serializer.errors, status=status.HTTP_400_BAD_REQUEST)	

3) updater

# data : 입력 데이터
# obj : 수정할 object
serializer = Serializer(obj, data=data)
serializer.save()

: create와 사용법이 동일하나 serializer를 선언할 때 수정할 object를 같이 넣어준다.

class UserView(APIView):
	# 회원 수정
    def put(self, request):
        user = request.user
        if user.is_anonymous:
            return Response({"error": "로그인 후 이용해주세요", status=status.HTTP_400_BAD_REQUEST}
        
        # 기본적인 사용 방법은 validator, creater와 다르지 않다.
        # update를 해줄 경우 obj, data(수정할 dict)를 입력한다.
        # partial=True로 설정해 주면 일부 필드만 입력해도 에러가 발생하지 않는다.
        user_serializer = UserSerializer(user, data=request.data, partial=True)

        if user_serializer.is_valid():
            # validator를 통과했을 경우 데이터 저장
            user_serializer.save()
            return Response({"message": "정상"}, status=status.HTTP_200_OK)
        
        return Response(user_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

3. serializer custom 기능에 대한 이해

1) custom validator

: 기본적인 validator 이후에 별개로 동작한다.

class UserSerializer(serializers.ModelSerializer):
    ...
    # validate 함수 선언 시 serializer에서 자동으로 해당 함수의 validation을 해줌
    def validate(self, data):
        # custom validation pattern
        if data.get("userprofile", {}).get("age", 0) < 12:
            # validation에 통과하지 못할 경우 ValidationError class 호출
            raise serializers.ValidationError(
                    # custom validation error message
                    detail={"error": "12세 이상만 가입할 수 있습니다."},
                )

        # validation에 문제가 없을 경우 data return
        return data
    ...

2) custom creator

serializer = Serializer(data=data)
serializer.save()

에서 .save() 메소드를 통해 동작하고 기존의 creator 코드를 덮어 씌우고 대신 동작한다.

class UserProfileSerializer(serializers.ModelSerializer):
    # hobby는 데이터를 직렬화 할 때, get_hobbys는 profile을 등록할 떄 사용된다.
    hobby = HobbySerializer(many=True, required=False, read_only=True)
    get_hobbys = serializers.ListField(required=False)

    class Meta:
        model = UserProfile
        fields = ["birthday", "age", "introduction", "hobby", "get_hobbys"]

class UserSerializer(serializers.ModelSerializer):
    userprofile = UserProfileSerializer()
    def create(self, validated_data):
        # object를 생성할때 다른 데이터가 입력되는 것을 방지하기 위해 미리 pop 해준다.
        user_profile = validated_data.pop('userprofile')
        get_hobbys = user_profile.pop("get_hobbys", [])

        # User object 생성
        user = User(**validated_data)
        user.save()

        # UserProfile object 생성
        user_profile = UserProfile.objects.create(user=user, **user_profile)
        
        # hobby 등록
        user_profile.hobby.add(*get_hobbys)
        user_profile.save()
	...
    class Meta:
        model = User
        fields = ["username", "password", "fullname", "email", "userprofile"]

3) custom updater

serializer = Serializer(obj = data=data)
serializer.save()

에서 .save() 메소드를 통해 동작하고 기존의 updater 코드를 덮어 씌우고 대신 동작한다.

class UserSerializer(serializers.ModelSerializer):
    userprofile = UserProfileSerializer()
    ...
    def update(self, instance, validated_data):
        # instance에는 입력된 object가 담긴다.
        for key, value in validated_data.items():
            if key == "password":
                instance.set_password(value)
                continue
            
            setattr(instance, key, value)
        instance.save()
        return instance
    ...
    class Meta:
        model = User
        fields = ["username", "password", "fullname", "email", "userprofile"]

스터디영상

https://youtu.be/HR1b2hrxvbY

profile
kimphysicsman

0개의 댓글