[Django] nested serializer와 create()의 역할, pop()의 사용 이유-2025-04-17

정지은·2025년 4월 17일
0

나머지공부

목록 보기
17/17

nested serializercreate()의 역할, 그리고 pop()의 사용 이유


객체를 -> 딕셔너리로 만드는게 목적


class ProductSerializer(serializers.ModelSerializer):
    
    category = CategorySerializer() # write를 할려면 read only를 지우기
    
    class Meta:
        model = Product
        fields = "__all__"
        
    def create(self, validated_data):
        category_data = validated_data.pop("category")
        
        # 카테고리 저장/조회
        category, _ = Category.objects.get_or_create(**category_data)
        product = Product.objects.create(**validated_data,category=category)
        return product

상황 정리

ProductSerializerProduct 모델을 직렬화할 때, category 필드를 CategorySerializer로 nested 처리하고 있어.

category = CategorySerializer()

즉, Product 안에 있는 category는 그냥 id 같은 외래키가 아니라, 직접 category 객체 정보(예: name, description 등)를 포함해서 serialize / deserialize 하겠다는 거야.


1. pop()을 하는 이유

category_data = validated_data.pop("category")

왜 필요할까?

validated_data는 원래 Product 모델에 해당하는 데이터만 있어야 Product.objects.create(**validated_data)가 동작해.

근데 지금 validated_data에는 category라는 딕셔너리형 데이터도 같이 들어있어. (왜냐하면 nested serializer를 사용하고 있으니까)

예를 들어 아래와 같은 JSON이 들어오면:

{
  "name": "삼성 TV",
  "price": 1200000,
  "category": {
    "name": "전자제품"
  }
}

Django는 category={"name": "전자제품"} 이런 dict는 바로 Product.objects.create()에서 쓸 수 없어. category는 FK이니까 이미 저장된 Category 모델 인스턴스여야 하거든.

그래서 먼저 category 관련 dict 데이터를 꺼내야 해 — 그게 pop("category")이야.


2. create() 메서드의 역할

def create(self, validated_data):
    category_data = validated_data.pop("category")
    
    # 카테고리 저장/조회
    category, _ = Category.objects.get_or_create(**category_data)
    product = Product.objects.create(**validated_data, category=category)

    return product

이 메서드는 어떤 역할을 하냐면?

  1. category_data를 꺼내서 (pop)
  2. 이미 있는 Category가 있으면 가져오고 없으면 새로 만들고 (get_or_create)
  3. Category 인스턴스를 다시 validated_data에 넣어서
  4. Product 모델 인스턴스를 생성하는 것

📌 즉, 이 코드는 Nested 데이터 구조를 처리하는 커스텀 로직이야.


정리

항목설명
validated_data.pop("category")Product 모델에 직접 쓸 수 없는 nested dict를 분리
Category.objects.get_or_create()중복되지 않게 카테고리를 저장하거나 기존 걸 재사용
Product.objects.create(...)분리한 카테고리 인스턴스를 포함해 Product 생성
create()serializer.save() 호출 시 실행되는 메서드 (직접 override한 것)

혹시 이걸 update()할 때는 또 다르게 해야 하는데, 그것도 설명해줄까?

0개의 댓글