ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Django REST framework] Routers(작성중)
    언어/파이썬 & 장고 2016. 8. 9. 13:31

    Routers

    Rails와 같은 몇 web framework들은 들어오는 request를 핸들링하여 logic과 어플리케이션을 위한 URL을 어떻게 매핑할지를 자동으로 결정하는 기능을 제공합니다. REST framework는 장고에 자동적인 URL 라우팅 기능을 지원하고 신속하고 일관성 있는 방법을 제공합니다.

    Usage

    SimpleRouter에 대한 예제입니다.

    from rest_framework import routers
    
    router = routers.SimpleRouter()
    router.register(r'users', UserViewSet)
    router.register(r'accounts', AccountViewSet)
    urlpatterns = router.urls

    register() method는 2개의 필수 argument가 있습니다.

    • prefix - route의 집합들을 사용하기 위한 URL prefix
    • viewset - viewset 클래스

    추가적으로 argument를 받을 수 있습니다.

    • base_name - base는 생성된 URL 이름을 사용합니다. 만약 설정되어 있지 않은 경우 basename은 자동적으로 viewset의 attribute queryset을 기반하여 생성합니다. 만약 viewset은 queryset attribute를 포함하지 않는다면, 사용자는 viewset을 등록할 때, base_name을 지정해야 합니다.

    URL패턴을 생성하는 예입니다.

    • URL pattern: ^users/$ Name: 'user-list'
    • URL pattern: ^users/{pk}/$ Name: 'user-detail'
    • URL pattern: ^accounts/$ Name: 'account-list'
    • URL pattern: ^accounts/{pk}/$ Name: 'account-detail'

    base_name argument는 view name 패턴의 초기 부분을 구체화하기 위해 사용됩니다. 위 예를 들어, user 또는 account 부분입니다.

    일반적으로 사용자는 base_name argument를 구체화할 필요가 없지만 사용자가 정의한 custom get_queryset method에 viewset이 위치해 있다면 viewset은 .queryset attribute 집합을 가질 수 없습니다. 만약 viewset을 등록한다고 노력한다면 아래와 같은 에러를 볼 수 있습니다.

    'base_name' argument not specified, and could not automatically determine the name from the viewset, as it does not have a '.queryset' attribute.

     이 의미는 사용자는 모델이름으로부터 자동적으로 결정되지 않은 viewset을 등록할 때, base_name argument를 명시하는 것이 필요합니다.

    Using include with routers

    router 인스턴스의 .urls attribute는 단순하게 URL 패턴의 표준 list입니다. 사용자가 URL들을 include하는 방법은 다양한 스타일이 존재합니다.

    예를 들어, router.urls를 존재하는 view의 list에 붙일 수 있습니다.

    router = routers.SimpleRouter()
    router.register(r'users', UserViewSet)
    router.register(r'accounts', AccountViewSet)
    
    urlpatterns = [
        url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
    ]
    
    urlpatterns += router.urls


    상대적으로 django의 include function을 사용할 수 있습니다.

    urlpatterns = [
        url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
        url(r'^', include(router.urls)),
    ]


    router URL은 또한 네임스페이스가 될 수 있습니다.

    urlpatterns = [
        url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
        url(r'^api/', include(router.urls, namespace='api')),
    ]


    hiperlinked serializers와 함께 네임스페이스를 사용한다면 사용자는 모든 serializer들에 있는 view_name 파라미터가 올바르게 namespace에 반영이 되었는지 확인하는 것이 필요합니다. 위의 예를 들어, 사용자의 상세 view에 hyperlinked된 serializer field들을 위해 view_name='api:user-detail' 같은 파라미터를 include하는 것을 필요로 합니다.

    Extra link and actions

    @detail_route 또는 @list_route 함께 decorated된 viewset의 모든 method들도 route가 될 수 있습니다. 예로 아래 UserViewSet 클래스로 볼 수 있습니다.

    from myapp.permissions import IsAdminOrIsSelf
    from rest_framework.decorators import detail_route
    
    class UserViewSet(ModelViewSet):
        ...
    
        @detail_route(methods=['post'], permission_classes=[IsAdminOrIsSelf])
        def set_password(self, request, pk=None):
            ...


    URL패턴은 추가적으로 발생이 됩니다.

    • URL pattern: ^users/{pk}/set_password/$ Name: 'user-set-password'

    만약 custom action을 위해 발생된 기본 URL을 사용하지 않기를 원한다면 대신 url_path 파라미터를 사용할 수 있습니다. 예를 들어, custom action을 위해 ^users/{pk}/change-password/$의 URL을 변경하기를 원한다면 아래와 같이 사용할 수 있습니다.

    from myapp.permissions import IsAdminOrIsSelf
    from rest_framework.decorators import detail_route
    
    class UserViewSet(ModelViewSet):
        ...
    
        @detail_route(methods=['post'], permission_classes=[IsAdminOrIsSelf], url_path='change-password')
        def set_password(self, request, pk=None):
            ...

    위의 예제는 다음 URL 패턴을 발생시킵니다.

    • URL pattern: ^users/{pk}/change-password/$ Name: 'user-change-password'

    API Guide

    SimpleRouter - 작성중


    댓글