개발 일기

Django restframework ModelViewSet Delete, Update

친구들안녕 2021. 6. 7. 20:47

서론

개인적인 공부중 애로사항 및 해결 방법을 찾아서 나열한 게시글입니다.

찾으시는 내용이 없을 수 있습니다.

 

 

본론

Front에서 Comment Update, Delete를 사용하기 위해 코드를 짜던중...

 

Delete는 별 이상 없이 진행되나 Update에서 문제가 발생했다.

serializer = self.get_serializer('author'~~, 'comment'~~)

이렇게 author를 넣었는데 author가 Null 취급하여 Update가 되지가 않는 것이다...

한참을 혼자 이리저리 집어넣다가 하루가 다 가고서야 소스코드를 봤다.

 

UpdateModelMixin

def update 부분을 보니까 serializer에 data만 넣는 게 아니고 instance라는 부분을 넣는 것을 알 수 있다.

instance는 get_object()로 가져오는 것을 보고 위로 쭉쭉 올라가 봤다

 

ModelViewSet -> GenericViewSet으로 이동
GenericViewSet-> GenericAPIView로 이동, ViewSetMixin은 다른분야라서 뺐다

GenericViewSet부터 get_object, get_queryset이 포함된다고 한다.

ViewSetMixin은 as_view() 관련이므로 넘어가고 GenericAPIView로 들어가 보자

 

GenericAPIView의 get_object

GenericAPIView의 get_object만 캡처해왔다.

대충 코드들을 보니 kwargs의 key를 가져와서 object로 반환해서 return 하나보다.

print 하면 나는 comment만 떡 하니 나와서 객체인 줄 몰랐는데 객체인가 보다.

 

아무튼 출력해보면 update 하기 이전의 내 Comment가 보였다.

그래서 업데이트 시 instance를 주고 update 할 data를 줬더니 update가 적용됐다.

아무래도 업데이트 전 instance를 data로 교체하는 듯하다.

instance가 object이니 author나 post 같은 기본 내용들은 들어간 상태로 comment만 교체되는 듯하다.

 

 

결론

마지막으로 적용한 Update, Delete 내 코드들

ModelViewSet에 정의한 코드이다.

UpdateMixin 코드에서 그대로 복사한 뒤 필요 없는 코드들은 지웠다.

Update, Delete시 본인이 요청한 건지 확인하기 위해 재정의 하는데 내가 해보겠다는 고집 때문에 하루가 다 갔다.

물론 내가 해보고 싶어서 소스코드를 안 본 잘못이지만... :(

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        comment = get_object_or_404(Comment, pk=kwargs['pk'])
        if request.user == comment.author:
            serializer = self.get_serializer(instance, data=request.data)
            serializer.is_valid(raise_exception=True)
            self.perform_update(serializer)
            return Response(serializer.data, status=status.HTTP_204_NO_CONTENT)

        return Response(status=status.HTTP_400_BAD_REQUEST)

    def destroy(self, request, *args, **kwargs):
        comment_pk = self.kwargs['pk']
        comment = get_object_or_404(Comment, pk=comment_pk)
        if request.user == comment.author:
            instance = self.get_object()
            self.perform_destroy(instance)
            return Response(status=status.HTTP_204_NO_CONTENT)
        return Response({"data": request.data}, status=status.HTTP_400_BAD_REQUEST)

 

 

 

참조

https://github.com/encode/django-rest-framework/blob/61e7a993bd0702d30e3049179000bc7c5f284781/rest_framework/viewsets.py#L235

 

encode/django-rest-framework

Web APIs for Django. 🎸. Contribute to encode/django-rest-framework development by creating an account on GitHub.

github.com