perform_create: request.user와 같은 추가 정보 주입하기

ViewSet의 perform_create 메서드를 오버라이드하여 클라이언트 데이터 외에 서버 측 정보를 추가로 주입해서 모델 객체를 생성하는 방법

perform_create가 필요한가?

클라이언트가 보내는 데이터만으로는 객체 생성에 필요한 모든 정보가 부족한 경우가 많음. 예를 들어 블로그 게시물 작성 시 클라이언트는 title, content만 보내고 author는 서버에서 현재 로그인한 사용자로 자동 설정해야 함. 클라이언트가 author_id를 직접 보낼 수 있다면 다른 사용자 이름으로 게시물 작성이 가능한 보안 문제 발생

perform_create의 동작 흐름

  1. 클라이언트 POST 요청

  2. get_serializer(data=request.data) - Serializer 인스턴스 생성

  3. serializer.is_valid(raise_exception=True) - 유효성 검사

  4. self.perform_create(serializer) 호출 - 여기서 추가 정보 주입

  5. serializer.save() - 실제 DB 저장

  6. 201 Created 응답 반환

실전 코드 예제

models.py

class Post(models.Model):
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

serializers.py

class PostSerializer(serializers.ModelSerializer):
    author = serializers.ReadOnlyField(source='author.username')
    
    class Meta:
        model = Post
        fields = ['id', 'author', 'title', 'content', 'created_at']

views.py

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permission_classes = [permissions.IsAuthenticated]

    def perform_create(self, serializer):
        serializer.save(author=self.request.user)

실무 팁과 주의사항

perform_update도 함께 사용

def perform_update(self, serializer):
    serializer.save(updated_by=self.request.user)

다양한 정보 주입 가능

  • IP 주소: serializer.save(author=self.request.user, created_ip=request.META.get('REMOTE_ADDR'))

  • URL 파라미터: 중첩 라우트에서 상위 객체 ID를 자동으로 설정

Last updated