Framework/Django

시리얼라이저 오버라이딩

JM Lee 2023. 6. 19. 17:20
728x90

RecipeIngredient에 작성할 때

1. Ingredient에서 그 재료를 가져오거나

2. Ingredient에 없을 시 그 재료를 사용자가 직접 생성하는 방향

으로 코드를 짤 생각이다.

# Views.py
class RecipeIngredientView(APIView):
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]

    def post(self, request, article_id):
        serializer = RecipeIngredientCreateSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(
                article_id=article_id, ingredient_id=request.data.get("ingredient")
                # article_id는 전달받은 article_id를 사용하고,
                # ingredient_id는 요청 데이터에서 "ingredient" 키를 통해 전달받은 값을 사용
            )
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

하지만 여기서는 어림도 없음을 알 수 있다.

저장할 때, 두 가지의 경우를 모두 반영할 수는 없기 때문이다.

 

이럴 때 사용하는 것이 시리얼라이저에서의 오버라이딩이다.

save 함수를 새로 재정의하는 것은 이번에 처음 알았는데, 자주 써먹어야 할 좋은 수단인 것 같다.

def save(self, **kwargs): 
        ingredient_name = kwargs.get("ingredient_id", None) # kwargs를 통해 ingredient_id를 전달
        # ingredient_name 변수에 ingredient_id 값을 할당.
        if not ingredient_name:
            raise serializers.ValidationError({"ingredient_id": "재료를 입력해주세요"})
            # serializers.ValidationError 예외를 발생
        try:
            ingredient = Ingredient.objects.get(ingredient_name=ingredient_name)
        except:
            ingredient = Ingredient.objects.create(ingredient_name=ingredient_name)
            ingredient.save()
        return super().save(**kwargs)
        # 원래의 save 메서드를 실행하고, 새로 생성한 Ingredient 객체를 포함한 결과를 반환

 

일반적으로 create, update, save 메서드를 오버라이딩하여 객체의 생성, 업데이트, 저장 동작을 커스터마이즈하는 경우가 많지만, validate, to_representation, to_internal_value 등의 함수도 오버라이딩 할 수 있다.

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

taggit 공식 문서 읽어보기  (0) 2023.06.21
Queryset method 정리  (1) 2023.06.20
generics.ListCreateAPIView  (0) 2023.06.19
MtoM 마이그레이션 오류(through 옵션)  (0) 2023.06.16
DRF Response()  (0) 2023.06.16