해결된 질문
작성
·
325
0
ModelViewSet
APIView
urls
현재 유저페이지를 구현하고있습니다. 프로필 수정과 프로필의 디테일 정보를 보여주는 APIView를 만들고 로그인한 유저가 작성한 게시글을 보여주는 PostList view도 따로 만들얻는데 문득 이런 생각이 들더라고요 "ModelView을 커스텀하면 한번에 끝나는거 아닌가??"
그래서 수정해보려는데 문제가 생깁니다. 정규표현화한 username을 파라미터로 viewSet에 넘겨야 하는데 그 방법을 모르겠어요.
또 get_queryset에서도 username을 인자로 받아서 queryset.filter(author=username) 처럼 활용가능한지도 알고싶습니다.
답변 1
0
안녕하세요.
정규표현화한 username을 파라미터로 viewSet에 넘긴다는 접근보다는,
어떠한 http 요청이 있을 때 View를 통해서 처리를 한다는 개념으로 접근하시는 것이 좋습니다.
1) 그 http 요청에서 username을 요청 URL에 포함시켜서 요청을 하실 수도 있고,
이때 주소는 /userpage/myusername/ 처럼 될 수 있을 테구요.
2) 그 http 요청에서 username을 요청 URL에 Query String으로 추가해서 요청을 하실 수도 있습니다.
이때 주소는 /userpage/?username=myusername 처럼 될 수 있습니다.
1번 방법의 경우, path 정의 시에 Capture할 패턴을 정의하시면, 뷰 함수가 호출 시에 인자로 전달됩니다.
path("<username>/", user_page) 로 정의하시면, user_page 함수는 호출 시에 username 이름의 인자가 전달될 것이기에 username 이름의 인자를 받을 수 있어야 합니다. 그럼 함수 정의는 def user_page(request, username): 식이 될 것이구요.
클래스 기반 뷰로 정의한다면, get, post 등의 dispatch 메서드에서도 동일하게 def get(self, request, username) 과 같이 정의하실 수 있습니다. 그런데, get_queryset 메서드는 직접적으로 URL Captured Value가 전달되지 않습니다. 호출 순서 상으로 dispatch 메서드 호출 후에, get_object 메서드 호출 시에 내부적으로 get_queryset 메서드가 호출됩니다. (정확한 호출 순서는 DRF의 GenericAPIView 코드를 살펴보시길 추천드립니다.) 그러니 dispatch 메서드에서 멤버변수로 username을 저장한 후에, self.username = username
get_queryset에서 self.username을 참조하는 식으로 구현해보실 수 있습니다.
2번 방법의 경우에는 path에는 패턴을 정의하시지 않고, 뷰에서 request 객체를 통해 request.GET을 통해 쿼리스트링 목록을 조회하실 수 있고, DRF에서는 request.query_params 이름으로 requset.GET 보다는 좀 더 직관적인 이름으로 쿼리 스트링을 조회하실 수 있습니다. request.query_params는 이름만 다를 뿐, 내부적으로는 request.GET 입니다.
그리고, 장고는 마법이 아니라, 다른 언어/프레임워크에서는 당연히 여겨지는 반복을 줄여줄 수 있는 다양한 방법을 제공해주고 있습니다. 장고의 Rule/철학을 이해하시는 만큼 생산성 높은 좋은 코드를 쓰실 수 있으실 것입니다.
화이팅입니다. :-)
아. CBV에서는 self.kwargs 를 통해 URL Captured Value 목록을 dict 타입으로 조회할 수 있습니다. 굳이 instance variable로 넘길 필요가 없겠네요.
네 답변 감사드립니다!! 아직 ModelViewSet을 커스텀 하는것은 익숙치않아서 위에처럼 구현했지만 조금씩 공부를 더 해봐야겠네요.