APIView를 상속받는..
GenericAPIView를 상속받는..
GenericViewSet을 상속받는..
ModelViewSet은 mixins를 모두 상속받는다.
3단 추상화
....
Retrieve란?
mixinx.RetrieveModelsMixin에 구현되어있는 메서드이다.
찾고자 하는 모델의 세부 정보를 반환한다.
어떻게 찾고자 하는 모델을 알 수 있을까?
우선 RESTful 규칙에 지키며 통신이 이루어진다고 가정하자.
[GET] http://localhost/post/3
위와 같은 url은 id가 3인 post를 요청하는 것이다.
해당 url을 받아들일 수 있는 django의 urls.py를 보면
urlpatterns = [
path('post/<int:pk>', ...),
]
이런 식으로 되어있을 것이다.
여기서 GenericAPIView의 필드 2개의 역할을 짚고 넘어가자
lookup_field = 'pk'
lookup_url_kwarg = 'post_id'
얘네들은 get_object() 메서드에서 사용된다.
def get_object(self):
queryset = self.filter_queryset(self.get_queryset())
# Perform the lookup filtering.
lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
...
filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
obj = get_object_or_404(queryset, **filter_kwargs)
...
return obj
예외처리 구문을 제외한 핵심 로직만 가져왔다.
lookup_url_kwarg는 먼저 self.lookup_url_kwarg로 설정된다. 만약 없다면 self.lookup_field로 대체한다.
(self.lookup_field는 기본값이 'pk')
filter_kwargs의 정의를 보면 lookup_field는 모델의 attribute를 가리킴을 알 수 있다. (모델의 필드)
모델의 lookup_field의 값이 self.kwargs[lookup_url_kwarg]값과 일치하는 객체가 있다면 객체를 반환한다.
self.kwargs는 url로 넘어온 인자들이 저장되는 dict이다.
바로 <int:pk>에서 pk가 저장되는데
self.kwargs = {'pk': 3} 이렇게 저장되는 것이다.
따라서 간단히 정리하면
특정 객체를 찾고 싶다 -> 객체의 primary_key가 무엇인가?(일반적으로 'pk'를 사용하지만 'slug'도 종종 사용한다.)
-> 찾고자 하는 primary_key를 lookup_field('pk')로 설정한다. -> self.kwargs의 어떤 key값을 사용할 것인가? -> urls.py에서 <int:post_id>로 pk값을 받도록 설정했다. -> lookup_url_kwarg = 'post_id' 로 설정한다.
만약 쿼리셋을 통해서 객체를 가져오는 과정이 복잡하고 커스텀이 필요한 경우 get_object메서드를 오버라이딩해서 사용할 수 있다.
최종
class RetrieveModelMixin:
"""
Retrieve a model instance.
"""
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance)
return Response(serializer.data)
self.get_object() 메서드를 통해서 원하는 객체를 instance에 넣고, 그 인스턴스를 serializer에 넣으면 원하는 객체의 데이터를 json으로 가져올 수 있다!
'Back-End > Django' 카테고리의 다른 글
[Django] Serializer와 validate (TIP!) (0) | 2022.01.15 |
---|---|
[Django] DRF 구조 이해 #1 (APIView) (0) | 2022.01.11 |
[Django] django 기본 인증 시스템 커스텀(아이디, 이메일 로그인) (0) | 2022.01.03 |
[Django] DRF를 사용한 JWT Authentication #2 (0) | 2022.01.03 |
[Django] DRF를 사용한 JWT Authentication #1 (0) | 2022.01.03 |