preface

When you switch to Django REST Framework Developer, you’ll find a new router.register in addition to Django’s original URLPatterns path I thought the Django section would use the URLPatterns path, and the DRF section would use the router.register. In this Tutorial, I found the REST Framework for Django. Class – -based Views – English document | Tutorial 3: Class – -based Views – Chinese document), found that it may not be as simple as that.

content

The traditional way

To conclude, when we develop an API that inherits from the ApiView, we’ll use the traditional Django CBV to register routes in the URLPatterns path by calling the as_view method, as shown in the official documentation

from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views

urlpatterns = [
    url(r'^snippets/$', views.SnippetList.as_view()),
    url(r'^snippets/(?P<pk>[0-9]+)/$', views.SnippetDetail.as_view()),
]

urlpatterns = format_suffix_patterns(urlpatterns)

The snippetDetail is defined as follows:

Class snippetDetail (APIView): """ Retrieves, updates, or deletes a snippet example. """ def get_object(self, pk): try: return Snippet.objects.get(pk=pk) except Snippet.DoesNotExist: raise Http404 def get(self, request, pk, format=None): snippet = self.get_object(pk) serializer = SnippetSerializer(snippet) return Response(serializer.data) def put(self, request, pk, format=None): snippet = self.get_object(pk) serializer = SnippetSerializer(snippet, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def delete(self, request, pk, format=None): snippet = self.get_object(pk) snippet.delete() return Response(status=status.HTTP_204_NO_CONTENT)

A new way

The ViewSet, which inherits the Django REST Framework, uses the router.register to register routes.

Inherited from
ModelViewSetor
GenericViewSetSuch as to
ViewSetFor the suffix is counted.

Specific see reference Django REST framework is the official document (Tutorial 6: ViewSets & Routers – English document | Tutorial 6: ViewSets & Routers – Chinese document)

The key code is extracted below

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from snippets import views

# Create a router and register our viewsets with it.
router = DefaultRouter()
router.register(r'snippets', views.SnippetViewSet)
router.register(r'users', views.UserViewSet)

# The API URLs are now determined automatically by the router.
urlpatterns = [
    path('', include(router.urls)),
]

The SnippetViewSet is defined as follows. The SnippetViewSet is inherited from the ModelViewSet

from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import permissions
from rest_framework import viewsets

class SnippetViewSet(viewsets.ModelViewSet):
    """
    This viewset automatically provides `list`, `create`, `retrieve`,
    `update` and `destroy` actions.

    Additionally we also provide an extra `highlight` action.
    """
    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly,
                          IsOwnerOrReadOnly]

    @action(detail=True, renderer_classes=[renderers.StaticHTMLRenderer])
    def highlight(self, request, *args, **kwargs):
        snippet = self.get_object()
        return Response(snippet.highlighted)

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)

The relationship between the two approaches

Django’s URLPatterns path and Django’s REST Framework router. Register are not in opposition to each other. The DRF approach is essentially a wrapper around Django’s approach. We can also use the traditional as_view method in a class that inherits from ViewSet. This is explained in the appeal document. The action parameter of the as_view method is explicitly specified. Declare the mapping between methods such as GET, POST, PATCH, and specific functions.

from snippets.views import SnippetViewSet, UserViewSet, api_root
from rest_framework import renderers

snippet_list = SnippetViewSet.as_view({
    'get': 'list',
    'post': 'create'
})
snippet_detail = SnippetViewSet.as_view({
    'get': 'retrieve',
    'put': 'update',
    'patch': 'partial_update',
    'delete': 'destroy'
})
snippet_highlight = SnippetViewSet.as_view({
    'get': 'highlight'
}, renderer_classes=[renderers.StaticHTMLRenderer])
user_list = UserViewSet.as_view({
    'get': 'list'
})
user_detail = UserViewSet.as_view({
    'get': 'retrieve'
})