Rewriting our API using class-based views
使用类视图重写root views,只需要一点点重构。
from django.http import Http404 from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from .models import Course from .serializer import CourseSerializer class CourseList(APIView): ''' list all courses,or create a new course ''' def get(self,request,format=None): queryset = Course.objects.all() serializer = CourseSerializer(queryset,many=True) return Response(serializer.data) def post(self,request,format=None): serializer = CourseSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data,status=status.HTTP_201_CREATED) return Response(serializer.data,status=status.HTTP_400_BAD_REQUEST) class CourseDetail(APIView): ''' retrieve,update or delete a course isntance ''' def get_object(self,pk): try: return Course.objects.get(pk=pk) except Course.DoesNotExist: raise Http404 def get(self,request,pk,format=None): course = self.get_object(pk) serializer = CourseSerializer(course) return Response(serializer.data) def put(self, request, pk, format=None): course = self.get_object(pk) serializer = CourseSerializer(course, 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): course = self.get_object(pk) course.delete() return Response(status=status.HTTP_204_NO_CONTENT)
urlpatterns = [ path('admin/', xadmin.site.urls), path('course/', views.CourseList.as_view(),name='course_list'), path('course/<int:pk>/', views.CourseDetail.as_view() ,name='course_detail'), ] urlpatterns = format_suffix_patterns(urlpatterns) #使用类视图的url方法as_view()
Using mixins
使用类视图最大的好处就是可以行为重用
from rest_framework import mixins from rest_framework import generics from .models import Course from .serializer import CourseSerializer class CourseList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = Course.objects.all() serializer_class = CourseSerializer def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) #使用GenericAPIView建立view,提供核心功能。 #加入ListModelMixin和CreateModelMixin,提供.list()和.create()动作。 #然后把get和post方法绑定到相关动作上。 class CourseDetail(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView): queryset = Course.objects.all() serializer_class = CourseSerializer def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) def put(self, request, *args, **kwargs): return self.update(request, *args, **kwargs) def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs #再次使用GenericAPIView提供核心功能,然后提供.retrieve(), .update() and .destroy() actions.
Using generic class-based views
使用mixin类可以减少代码,但rest框架提供了一组已经mixin-in的通用视图,可以再次减少代码。
from rest_framework import generics from .models import Course from .serializer import CourseSerializer class CourseList(generics.ListCreateAPIView): queryset = Course.objects.all() serializer_class = CourseSerializer class CourseDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Course.objects.all() serializer_class = CourseSerializer