Henu
개발냥발
Henu
전체 방문자
오늘
어제
  • 분류 전체보기 (411)
    • DevOps (52)
      • Kubernetes (19)
      • Docker (14)
      • AWS (3)
      • Nginx (4)
      • Linux (4)
      • ArgoCD (1)
      • CN (2)
      • NATS (0)
      • Git (5)
    • Back-End (30)
      • Django (18)
      • Spring (5)
      • JPA (1)
      • MSA (5)
    • CS (87)
      • SystemSoftware (20)
      • OS (25)
      • Computer Architecture (16)
      • Network (23)
      • Database (2)
    • Lang (21)
      • Java (9)
      • Python (4)
      • C# (8)
    • Life (12)
    • 블록체인 (2)
    • Algorithm (204)
      • BOJ (160)
      • 프로그래머스 (19)
      • LeetCode (4)
      • SWEA (1)
      • 알고리즘 문제 해결 전략 (8)
      • DS, algorithms (7)
      • Checkio (5)
    • IT (2)

블로그 메뉴

  • GitHub
  • 글쓰기
  • 관리자

공지사항

  • Free!

인기 글

태그

  • docker
  • django
  • 다이나믹 프로그래밍
  • BFS
  • Network
  • Kubernetes
  • 백트래킹
  • DFS
  • boj
  • 프로그래머스

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Henu

개발냥발

[Django] ModelViewSet에서 Retrieve의 동작 원리
Back-End/Django

[Django] ModelViewSet에서 Retrieve의 동작 원리

2022. 1. 16. 23:56

 

 

 

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
    'Back-End/Django' 카테고리의 다른 글
    • [Django] Serializer와 validate (TIP!)
    • [Django] DRF 구조 이해 #1 (APIView)
    • [Django] django 기본 인증 시스템 커스텀(아이디, 이메일 로그인)
    • [Django] DRF를 사용한 JWT Authentication #2

    티스토리툴바