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 |