Django Rest Framework(DRF)의 CreateModelMixin을 상속받아 구현된 ViewSet과 ModelSerializer(혹은 BaseSerializer를 상속받아 구현된 serializer)를 보면 두 클래스 모두 create() 메소드를 가지고 있다. 이름도 같고 쓰임새도 비슷할 것 같은 두 메소드는 어떤 방식으로 다를까?
ViewSet
CreateModelMixin에는 create 메소드가 구현되어 있다.
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def perform_create(self, serializer):
serializer.save()
create 메소드는 request로 받아온 data를 serializer로 넘겨 처리한 후 response를 다시 넘기는 식으로 동작한다. 중간에 보면 perform_create 메소드가 있다. 이 메소드는 serializer.save() 를 호출한다. 실제로 model instnace를 생성하는 부분은 ViewSet이 아니라 serializer라는 것을 알 수 있다.
Serializer
BaseSerializer의 save() 를 보면 언제 model instance 생성하는지 알 수 있다.
def save(self, **kwargs): ... validated_data = {**self.validated_data, **kwargs}
if self.instance is not None:
self.instance = self.update(self.instance, validated_data)
assert self.instance is not None, (
'`update()` did not return an object instance.'
)
else:
self.instance = self.create(validated_data)
assert self.instance is not None, (
'`create()` did not return an object instance.'
)
return self.instance
Serializer에서 model instance가 주어지지 않는 경우 serializer는 create()를 호출한다. 즉 Serializer의 create() 에 직접적인 model instance 생성 로직이 들어간다. View를 가볍게 유지하고 실제 무겁고 복잡한 일들과 Validation은 Serializer가 처리하는 셈이다.
덕분에 생성 시점에 단순 인자 전달 같은 일은 ViewSet의 create() 이나 Serializer의 create()을 override하지 않고, validate을 신경쓰지 않고perform_create에서 처리할 수 있다.
# 예시
def perform_create(self, serializer):
serializer.save(user=self.request.user)