본문 바로가기
Django/Django Rest Framework

21. Django DRF serializer 심화 / validator

by S.T.Lee 2022. 6. 21.

serializer에는 데이터 직렬화 외에도 data validation, create, update 기능을 사용할 수 있다.

다른 말로 프런트앤드(포스트맨)에서 request를 보내주면 데이터가 유효한지 검증하고 생성 및 업데이트를 할 수 있다.

 

validator

serializer에서는 기본적으로 Meta class 내부 field에 포함되어 있는 항목에 맞게 validate를 진행한다.

 

예시

#views.py
class MakeArticle(APIView):   
    def post(self, request):
        user = request.user
        request.data['author'] = user.id
        article_serializer = ArticleSerializer(data=request.data)
        if article_serializer.is_valid(): #True or False
            article_serializer.save()
            return Response(article_serializer.data, status=status.HTTP_200_OK)
        
        return Response(article_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        
        
#request.data
"""
{
    "name":"title",
    "category": ["it"],
    "content" : "hello this is text",
    "view_start_date" : "2022-06-15",
    "view_end_date" : "2022-06-30"
}
""""
class ArticleSerializer(serializers.ModelSerializer):
    category = serializers.SerializerMethodField()
    comments = CommentSerializer(many=True, source='commnent_set', read_only=True)
    def get_category(self, obj):
        return [category.name for category in obj.category.all()]
    
    class Meta:
        model = ArticleModel
        fields = ['name', 'content', 'category', 'comments', 'author']

Tip

1) request.data의 모든 내용이 Meta fields에 전부 있을 필요 없다. 알아서 걸러내서 저장한다.

2) 하지만 field에 있는 내용이 없는건 안된다.

3) 로그인된 사용자에 한해서 사용되기 때문에 author가 추가되어야한다.

4) 하단의 사진과 같이 데이터가 들어가는데 category=[]해서 빈칸으로 들어간걸 볼 수 있다. 그 이유는 custom create을 안 만들어서 인데 추후에 다루겠지만 외래키가 들어가는것은 전부 custom create를 해줘야한다.

카테고리에 데이터가 들어가지 않았다

 

Serializer에 사용가능한 옵션

class UserSerializer(serializers.ModelSerializer):
    # 외래 키 관계에 있는 필드의 required를 설정하고 싶을 경우 인자로 넘겨줘야 한다.
    userprofile = UserProfileSerializer(required=False) # default : True
    ...
    class Meta:
        ...
        # 각 필드에 해당하는 다양한 옵션 지정
        extra_kwargs = {
            # write_only : 해당 필드를 쓰기 전용으로 만들어 준다.
            # 쓰기 전용으로 설정 된 필드는 직렬화 된 데이터에서 보여지지 않는다.
            'password': {'write_only': True}, # default : False
            'email': {
                # error_messages : 에러 메세지를 자유롭게 설정 할 수 있다.
                'error_messages': {
                    # required : 값이 입력되지 않았을 때 보여지는 메세지
                    'required': '이메일을 입력해주세요.',
                    # invalid : 값의 포맷이 맞지 않을 때 보여지는 메세지
                    'invalid': '알맞은 형식의 이메일을 입력해주세요.'
                    },
                    # required : validator에서 해당 값의 필요 여부를 판단한다.
                    'required': False # default : True
                    },
            }

 

view에서 사용 가능한 옵션들

# serializer의 인자에 object를 넣어 직렬화 된 데이터를 가져올 수 있다.
user = request.user
return Response(UserSerializer(user).data, status=status.HTTP_200_OK)

# object와 마찬가지로 queryset을 인자로 넣어 여러개의 직렬화 된 데이터를 가져올 수 있다.
hobbys = Hobby.objects.all()
# queryset을 인자로 넣을 경우 many=True 설정 필요하다.
return Response(HobbySerializer(hobbys, many=True).data, status=status.HTTP_200_OK)

# partial을 True로 설정할 경우 required field에 대한 validation을 수행하지 않는다.
# 주로 일부 필드를 update 할 때 사용된다.
user_serializer = UserSerializer(data=request.data, partial=True)

# raise_exception을 True로 설정할 경우 validation을 통과하지 못했을 때 exception을 발생시킨다.
user_serializer = UserSerializer(data=request.data, raise_exception=True)

 

Custom Validator

custom validator는 validator 이후에 동작한다.

custom validator는 validator와 별개로 동작한다.

  • validator는 데이터의 requierd, invalid 등을 판단하고 custom validator에서는 사용자가 원하는 validation을 추가로 검증 할 수 있다.
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

'Django > Django Rest Framework' 카테고리의 다른 글

23. DRF JWT란  (0) 2022.07.18
22. Django DRF serializer 심화 / updater  (0) 2022.06.22
20. Django DRF Q  (0) 2022.06.21
19. Django DRF orm 심화  (0) 2022.06.20
18. Django DRF permission_classes/admin, 사용자 별 권한 설정  (0) 2022.06.20