Serializer의 create () 및 ModelViewset의 create () perform_create () 사용시기


95

django-rest-framework모델 객체 생성과 관련 하여 주어진 문서를 명확히하고 싶습니다 . 지금까지 이러한 이벤트를 처리하는 방법에 대해 세 가지 접근 방식이 있음을 발견했습니다.

  1. Serializer의 create()메서드입니다. 다음은 문서입니다.

    class CommentSerializer(serializers.Serializer):
    
        def create(self, validated_data):
            return Comment.objects.create(**validated_data)
    
  2. ModelViewset create()메서드입니다. 선적 서류 비치

    class AccountViewSet(viewsets.ModelViewSet):
    
        queryset = Account.objects.all()
        serializer_class = AccountSerializer
        permission_classes = [IsAccountAdminOrReadOnly]
    
  3. ModelViewset perform_create()메서드입니다. 선적 서류 비치

    class SnippetViewSet(viewsets.ModelViewSet):
    
        def perform_create(self, serializer):
            serializer.save(owner=self.request.user)
    

이 세 가지 접근 방식은 애플리케이션 환경에 따라 중요합니다.

하지만 언제 각 create() / perform_create()기능 을 사용해야합니까 ??. 반면에 나는 modelviewset create()과 serializer의 단일 포스트 요청에 대해 두 개의 create 메서드가 호출되었다는 계정을 발견했습니다 create().

누구나 자신의 지식을 공유하여 설명 할 수 있기를 바라며 이것이 제 개발 과정에 큰 도움이 될 것입니다.

답변:


125
  1. create(self, validated_data)AND "prod"값을 각 모델 필드에 저장하기 전에 객체에 추가 세부 정보를 추가하는 데 사용 합니다 **validated_data. 이상적으로 말해서,이 형태의 "프 로딩"을 한 위치에서만 수행하기를 원하므로 create귀하 의 방법 CommentSerializer이 가장 좋습니다. 또한 자신의 데이터베이스에 계정을 저장하기 직전에 외부 API를 호출하여 사용자 계정을 만들 수도 있습니다. 이 create기능은와 함께 사용해야합니다 ModelViewSet. 항상 생각하십시오- "Thin views, Thick serializers".

예:

def create(self, validated_data):
    email = validated_data.get("email", None)
    validated.pop("email") 
    # Now you have a clean valid email string 
    # You might want to call an external API or modify another table
    # (eg. keep track of number of accounts registered.) or even
    # make changes to the email format.

    # Once you are done, create the instance with the validated data
    return models.YourModel.objects.create(email=email, **validated_data)
  1. create(self, request, *args, **kwargs)함수 는의 부모 인 클래스 ModelViewSet에서 정의됩니다 . 의 주요 기능은 다음과 같습니다.CreateModelMixinModelViewSetCreateModelMixin

    from rest_framework import status
    from rest_framework.response import Response
    
    
    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함수는 serializer에서 유효성 검사를 호출하고 올바른 응답을 생성합니다. 이것의 장점은 이제 애플리케이션 로직을 분리 할 수 ​​있고 평범하고 반복적 인 유효성 검사 호출과 응답 출력 처리에 대해 걱정하지 않아도된다는 것입니다. 이것은 create(self, validated_data)시리얼 라이저 (특정 애플리케이션 로직이 상주 할 수있는 위치)에서 발견 된 것과 함께 잘 작동 합니다.

  1. 이제 perform_create(self, serializer)한 줄의 코드 로 별도의 함수 가있는 이유를 물어볼 수 있습니다 !?!? 음, 이것의 주된 이유는 save함수를 호출 할 때 커스터마이징을 허용하기 위해서 입니다. 호출하기 전에 추가 데이터를 제공하고 싶을 수도 있습니다 save (예serializer.save(owner=self.request.user) 를 들어 우리가를 가지고 있지 않다면 and perform_create(self, serializer)를 재정의해야 할 것입니다. create(self, request, *args, **kwargs)그것은 단지 무겁고 지루한 작업을하는 믹스 인의 목적을 무너 뜨립니다.

도움이 되었기를 바랍니다!


안녕하세요! 지식을 공유해 주셔서 감사합니다! [정보] create(self, validated_data)시리얼 라이저에서, 그것은 데이터 유효성 검사 논리에 초점을 맞추고 있음을 의미? 그리고 그 이상은 주어진 serializer의 데이터를 응답으로 되 돌리는 데 도움이 될 수 있습니까?
Roel

1
아니요,이 시점에서 이미 모든 유효성 검사를 통과했습니다. 검증 된 데이터가 데이터베이스에 저장되기 직전에 사용자 지정하는 방법에 대해 이야기하고 있습니다. 내 대답에 예를 들어 보겠습니다.
Apoorv Kansal 2016

1
걱정하지 마세요. 더 많은 컨텍스트를 제공하기 위해 예를 추가했습니다.
Apoorv Kansal

1
그래, 그 데이터베이스에 개체를 저장합니다 마지막 줄은
Apoorv Kansal

1
그렇게 create시리얼 라이저 자체 기능이 있습니다 단지 당신이 할 때 호출 serializer.save(). 당신에 create(self, request)함수 내부 ( AccountViewSet)는 호출되지 않습니다 serializer.save()전혀 때문에, 유일한 인스턴스 생성이 호출에 발생된다 Account.objects.create_user(**serializer.validated_data).
Apoorv Kansal
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.