一、使用基于类的视图重写API
from django.http import Http404
from rest_framework import status
from rest_framework.decorators import api_view, APIView
from rest_framework.response import Response
from crm.models import Student
from crm.serializers import StudentSerializer
class StudentList(APIView):
"""
学生列表,创建视图
"""
def get(self, request, format=None):
objs = Student.objects.all()
serializer = StudentSerializer(objs, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = StudentSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class StudentDetail(APIView):
"""
查看,更新或者删除一个项目
"""
def get_object(self, pk):
try:
return Student.objects.get(pk=pk)
except Student.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
obj = self.get_object(pk)
serializer = StudentSerializer(obj)
return Response(serializer.data, status=status.HTTP_201_CREATED)
def put(self, request, pk, format=None):
obj = self.get_object(pk)
serializer = StudentSerializer(obj, 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):
obj = self.get_object(pk)
obj.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
重构路由
urlpatterns = [
path('students/', views.StudentList.as_view()),
path('students/<int:pk>', views.StudentDetail.as_view()),
]
二、使用mixins
使用基于类的视图的一大优点是,它允许我们轻松地组合且可重用的行为。
在实际开发过程中,对任何模型的创建/检索/更新/删除操作非常相似。REST framework
在mixin
类中实现了这些公共行为。
让我们看看如何使用mixin
类来组合视图。views.py
模块代码如下:
from rest_framework import status, mixins, generics
from rest_framework.decorators import APIView
from rest_framework.response import Response
from crm.models import Student
from crm.serializers import StudentSerializer
class StudentList(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
"""
返回所有的项目或者创建一个新项目
"""
queryset = Student.objects.all()
serializer_class = StudentSerializer
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
构建视图,并添加ListModelMixin
和CreateModelMixin
。
基类提供了核心功能,mixin
类提供了.list()
和.create()
操作。然后显式地将get
和post
方法绑定到适当的操作。
class StudentDetail(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
generics.GenericAPIView):
"""
查看,更新或者删除一个项目
"""
queryset = Student.objects.all()
serializer_class = StudentSerializer
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
类来提供核心功能,并在mixins
中添加.retrieve()
、.update()
和.destroy()
操作。
三、使用通用类视图
使用mixin
类,我们已经重写了视图,代码比以前少了一些,但是我们可以更进一步。上面的代码显然是可以公用的,而REST框架提供了一组已经混合在一起的通用视图,我们可以使用这些视图进一步精简我们的views.py
模块。
class StudentList(generics.ListCreateAPIView):
"""
返回所有的项目或者创建一个新项目
"""
queryset = Student.objects.all()
serializer_class = StudentSerializer
class StudentDetail(generics.RetrieveUpdateDestroyAPIView):
"""
查看,更新或者删除一个项目
"""
queryset = Student.objects.all()
serializer_class = ProjectSerializer