Preface
Django
developer turns to Django REST framework
developer, you will find that there is Django
based on the original urlpatterns path of 061c1981b75264.
Originally I thought that the Django
part would use the urlpatterns path, and the DRF
part would be the router.register, but later look at the Django REST framework
official document ( Tutorial 3: Class-based Views-English document | Tutorial 3: Class-based Views- Chinese document ), I found that things are not so simple.
content
Traditional way
Let me talk about the conclusion first, when the api
we developed is inherited from APIView
, then use the traditional Django
CBV
, and register the route in the urlpatterns path by calling the as_view
method, just like the example in the official document
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)
SnippetDetail
is defined as follows:
class SnippetDetail(APIView):
"""
检索,更新或删除一个snippet示例。
"""
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)
New way
The inheritance exclusive Django REST framework
of ViewSet
, is used router.register
registered routes.
Inherited fromModelViewSet
orGenericViewSet
withViewSet
as the suffix are counted.
For details, Django REST framework
refer to the official document (161c1981b7546b Tutorial 6: ViewSets & Routers-English document | Tutorial 6: ViewSets & Routers-Chinese document )
Extract the key code 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 definition of SnippetViewSet is as follows, you can see that SnippetViewSet is inherited from 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 ways
Django's urlpatterns path
and Django REST framework's router.register
are not opposites, and there is no need to choose one of DRF
. The method of Django
method. As for why such packaging is required for better organization api
Similarly, we can use the traditional as_view
ViewSet
. This is explained in detail in the appeal document. The general meaning is to explicitly state the action
as_view
method. This parameter is a dictionary type, and declares such as get , Post, patch and other methods and the mapping relationship between 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'
})
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。