Create와 Perform_Create
코드로 보기
장고의 ViewSet은 기본적으로 GenericAPIView라는 클래스를 상속 받기 때문에 'list', 'create', 'retrieve'와 'update', 'destory' 메소드를 자동으로 생성해준다. 여기서 create는 RestAPI의 post 메소드와 매칭되어 생성되는데 코드로 보면 아래와 같다.
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()
여기서 우리는 아래와 같은 점들을 알 수 있다.
- 시리얼라이저를 가져와서 벨리데이션 실행
- perform_create 실행
- 헤더를 만들어주고 생성 성공 response 반환
위 코드에서 self.perform_create 부분이 있는데 여기서 serializer.save()를 실행한다. 만약 장고가 perform_create를 지원하지 않았다면 우리는 save 전에 serializer에 대해 하고 싶은 선처리가 있을 때 항상 create를 다시 선언해야 했을 것이다. 그러면 perform_create는 어떤 경우에 사용할까?
Perform_Create 사용
장고 튜토리얼 6장의 예제를 보면 perform_create를 선언하는 부분이 있다. 해당 부분에선 아래와 같이 선언해준다.
class SnippetViewSet(viewsets.ModelViewSet):
"""
This ViewSet automatically provides `list`, `create`, `retrieve`,
`update` and `destroy` actions.
Additionally we also provide an extra `highlight` action.
"""
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]
@action(detail=True, renderer_classes=[renderers.StaticHTMLRenderer])
def highlight(self, request, *args, **kwargs):
snippet = self.get_object()
return Response(snippet.highlighted)
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
코드를 보면 serializer.save에 owner=self.request.user 인자를 전달해주고 있다. Serializer 부분 코드는 아래와 같다.
class SnippetSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.ReadOnlyField(source="owner.username")
highlight = serializers.HyperlinkedIdentityField(
view_name="snippet-highlight", format="html"
)
class Meta:
model = Snippet
fields = [
"url",
"id",
"highlight",
"owner",
"title",
"code",
"linenos",
"language",
"style",
]
perform_create를 통해서 serializer의 owner를 self.request.user로 초기화 해주는 모습을 볼 수 있다. perform_create는 이와 같이 create를 재 정의 하지 않고도 Serializer의 선행 처리를 쉽게 할 수 있게 해준다. 그리고 저장 시 커스텀 벨리데이션 체크, 외부 api 연결 여부 확인 등 하고 싶은 다른 액션을 추가로 쉽게 실행 시킬 수 있다.
'Backend > Django' 카테고리의 다른 글
Django queryset 파보기 (0) | 2024.03.12 |
---|---|
Django Serializer의 Fields (1) | 2024.03.12 |
Django Tutorial 6: ViewSets & Routers (0) | 2024.03.12 |
Django Tutorial 5: Relationships & Hyperlinked APIs (0) | 2024.03.12 |
Django Tutorial 4: Authentication & Permissions (0) | 2024.03.10 |