본문 바로가기
Python/Django

[Django] request.data immutable

by 혀나Lee 2017. 1. 13.

django 에서 request.data의 데이터를 수정하려고 하면 immutable 에러가 발생한다.


위 에러를 해결하기 위해서는 아래의 방법을 사용한다.

단순히 request.data 를 사용하고자 하는 경우

단순히 request.data 를 가져와서 key를 추가하고자 하는 경우는 아래의 방법으로 쉽게 해결할 수 있을 것이다.
아래는 POST의 경우만 체크한 거니 

1. copy() 함수 사용

data = request.data.copy()
data['newKey'] = value

2. __setitem__() 함수 사용

request.data.__setitem__(newKey, value)

DB에 저장 전, request.data 에 key를 추가하고자 하는 경우

이 경우는 위의 함수를 사용해서는 해결이 안 될 것이다. 물론 로컬에서 테스트할 때는 된다. 로컬과 서버는 환경이 다르기 때문에 서버의 API를 호출하고자 하면 또 immutable 에러가 발생할 것이다. 
보통 이 경우는 django serializer 의 viewset 형태로 구현되어 있는 API일 경우에 사용된다. 

DjangoRestFramework 버전에 따라 사용 방법이 다르니 아래를 참고한다. 
내용은 request.data 에 owner라는 key로 'newValue' 의 값을 넣는 것이다.

v3. perform_create() 함수 사용

def perform_create(self, serializer):
    serializer.save(owner='newValue')

v2. pre_save() 함수 사용

def pre_save(self, obj):

    obj.owner = 'newValue'


이유를 살펴보면 아래와 같다.


django viewset의 create() 함수에서 아래의 함수를 호출한다.

super(TestViewSet, self).create(request, *args, **kwargs)

super().create() 함수를 클릭하여 구현된 내용을 보면 아래와 같다.

class CreateModelMixin(mixins.CreateModelMixin):
"""
Create a model instance.
"""
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)
self._get_cache_object().clear()
return Response(serializer.data, status=status.HTTP_201_CREATED,
headers=headers)

CreateModelMixin 내부에서 serializer를 확인 후, perform_create() 함수를 호출하는데 만약 perform_create() 함수를 override 하면 내가 구현한 함수가 호출이 되는 것이다.

댓글