r잡초처럼
바른 프로그래밍
r잡초처럼
전체 방문자
오늘
어제
  • 분류 전체보기 (124)
    • FastAPI (7)
    • 끄적끄적 (2)
    • Python (17)
    • Django (31)
    • Database (2)
    • Docker (7)
    • 디자인패턴 (2)
    • CS 공부 (12)
      • 알고리즘 (2)
      • 자료 구조 (1)
      • 네트워크 (7)
      • IT 지식 (1)
      • 운영체제 (1)
    • 기타 팁들 (10)
    • Aws (2)
    • 독서 (1)
    • 코딩테스트 공부 (1)
      • 백준 (0)
      • 프로그래머스 (1)
    • DevOps (13)
    • TIL (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 모두의 네트워크
  • 상속과 컴포지션
  • CS 지식
  • 랜 카드
  • validate
  • Batch
  • 네트워크
  • preonboarding
  • cp949
  • 7장
  • dotenv
  • 5장 회사에서 하는 랜 구성
  • 파이썬 클린 코드
  • 6장
  • pytest
  • docker
  • 물리 계층
  • fastapi
  • 상속 안티 패턴
  • depends
  • query param
  • encoding
  • 컴퓨터 기본 지식
  • 완벽한 IT 인프라 구축을 위한 Docker
  • pycharm
  • 책 리뷰
  • poetry
  • 전기 신호
  • 케이블의 종류
  • 랜과 왠

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
r잡초처럼

바른 프로그래밍

카테고리 없음

[DRF] Third Party Packages - DRF Nested Routers

2023. 2. 27. 21:48

중첩 관계를 표현하는 REST API를 표현해 주는 Third Party Packages를 공부해보자. 

 

Installation

pip install drf-nested-routers

 

Quickstart

다음과 같은 url을 만든다고 하자.

/domain/ <- Domains list
/domain/{pk}/ <- One domain, from {pk}
/domain/{domain_pk}/nameservers/ <- Nameservers of domain from {domain_pk}
/domain/{domain_pk}/nameservers/{pk} <- Specific nameserver from {pk}, of domain from {domain_pk}
# urls.py
from rest_framework_nested import routers
from views import DomainViewSet, NameserverViewSet
(...)

router = routers.SimpleRouter()
router.register(r'domains', DomainViewSet)

domains_router = routers.NestedSimpleRouter(router, r'domains', lookup='domain')
domains_router.register(r'nameservers', NameserverViewSet, basename='domain-nameservers')
# 'basename' is optional. Needed only if the same viewset is registered more than once
# Official DRF docs on this option: http://www.django-rest-framework.org/api-guide/routers/

urlpatterns = [
    path(r'', include(router.urls)),
    path(r'', include(domains_router.urls)),
]
# views.py

## For Django' ORM-based resources ##

class NameserverViewSet(viewsets.ModelViewSet):
    def get_queryset(self):
        return Nameserver.objects.filter(domain=self.kwargs['domain_pk'])

## OR: non-ORM resources ##

class NameserverViewSet(viewsets.ViewSet):
    def list(self, request, domain_pk=None):
        nameservers = self.queryset.filter(domain=domain_pk)
        (...)
        return Response([...])

    def retrieve(self, request, pk=None, domain_pk=None):
        nameservers = self.queryset.get(pk=pk, domain=domain_pk)
        (...)
        return Response(serializer.data)

Infinite-depth Nesting

lv.3 수준 깊이 예제를 살펴보자. 

/clients/
/clients/{pk}/
/clients/{client_pk}/maildrops/
/clients/{client_pk}/maildrops/{pk}/
/clients/{client_pk}/maildrops/{maildrop_pk}/recipients/
/clients/{client_pk}/maildrops/{maildrop_pk}/recipients/{pk}/
# urls.py
router = DefaultRouter()
router.register(r'clients', ClientViewSet, basename='clients')
## generates:
# /clients/
# /clients/{pk}/

client_router = routers.NestedSimpleRouter(router, r'clients', lookup='client')
client_router.register(r'maildrops', MailDropViewSet, basename='maildrops')
## generates:
# /clients/{client_pk}/maildrops/
# /clients/{client_pk}/maildrops/{pk}/

maildrops_router = routers.NestedSimpleRouter(client_router, r'maildrops', lookup='maildrop')
maildrops_router.register(r'recipients', MailRecipientViewSet, basename='recipients')
## generates:
# /clients/{client_pk}/maildrops/{maildrop_pk}/recipients/
# /clients/{client_pk}/maildrops/{maildrop_pk}/recipients/{pk}/

urlpatterns = [
    path(r'', include(router.urls)),
    path(r'', include(client_router.urls)),
    path(r'', include(maildrops_router.urls)),
]
# views.py
class ClientViewSet(viewsets.ViewSet):
    serializer_class = ClientSerializer

    def list(self, request,):
        queryset = Client.objects.filter()
        serializer = ClientSerializer(queryset, many=True)
        return Response(serializer.data)

    def retrieve(self, request, pk=None):
        queryset = Client.objects.filter()
        client = get_object_or_404(queryset, pk=pk)
        serializer = ClientSerializer(client)
        return Response(serializer.data)


class MailDropViewSet(viewsets.ViewSet):
    serializer_class = MailDropSerializer

    def list(self, request, client_pk=None):
        queryset = MailDrop.objects.filter(client=client_pk)
        serializer = MailDropSerializer(queryset, many=True)
        return Response(serializer.data)

    def retrieve(self, request, pk=None, client_pk=None):
        queryset = MailDrop.objects.filter(pk=pk, client=client_pk)
        maildrop = get_object_or_404(queryset, pk=pk)
        serializer = MailDropSerializer(maildrop)
        return Response(serializer.data)


class MailRecipientViewSet(viewsets.ViewSet):
    serializer_class = MailRecipientSerializer

    def list(self, request, client_pk=None, maildrop_pk=None):
        queryset = MailRecipient.objects.filter(mail_drop__client=client_pk, mail_drop=maildrop_pk)
        serializer = MailRecipientSerializer(queryset, many=True)
        return Response(serializer.data)

    def retrieve(self, request, pk=None, client_pk=None, maildrop_pk=None):
        queryset = MailRecipient.objects.filter(pk=pk, mail_drop=maildrop_pk, mail_drop__client=client_pk)
        maildrop = get_object_or_404(queryset, pk=pk)
        serializer = MailRecipientSerializer(maildrop)
        return Response(serializer.data)
# serializers.py
class ClientSerializer(HyperlinkedModelSerializer):
    class Meta:
        model = Client
        fields = (...)


class MailDropSerializer(NestedHyperlinkedModelSerializer):
    parent_lookup_kwargs = {
        'client_pk': 'client__pk',
    }
    class Meta:
        model = MailDrop
        fields = (...)


class MailRecipientSerializer(NestedHyperlinkedModelSerializer):
    parent_lookup_kwargs = {
        'maildrop_pk': 'mail_drop__pk',
        'client_pk': 'mail_drop__client__pk',
    }
    class Meta:
        model = MailRecipient
        fields = (...)

참고

https://github.com/alanjds/drf-nested-routers

    r잡초처럼
    r잡초처럼
    오늘보다 내일 더 나은 개발자가 되기 위한 노력을 기록하는 블로그 입니다.

    티스토리툴바