CBV视图的好处
DRF自带的几种CBV
- 基础类APIView
- Mixins和GenericAPI类混搭
- 通用视图类generics.*的类,如generics.ListCreateAPIView
- 视图集ViewSet和ModelViewSet
以上模式各有各的好,有各自适合的情景,下面一一学习。
APIView
特点
- 继承于django的view类
- 支持多种请求方法,GET POST PUT PATCH DELETE
- 封装了django的request,通过request.data获取数据
- 支持插拔式认证、权限和限流
接下来,使用APIView来重写之前的view
"""
使用VPIview重写views
"""
from rest_framework.views import APIView
from django.http import Http404
class UserList(APIView):
"""
处理:
所有用户列表
新增用户
共性:
不需要携带ID相关的参数
"""
def get(self, request):
users = User.objects.all()
serializer = UserModelSerializer(users, many=True)
return Response(serializer.data)
def post(self, request):
serializer = UserModelSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class UserDetail(APIView):
"""
处理:
单个用户详情
更新、删除单个用户
共性:
需要ID相关参数
"""
def get_obj(self, user_id):
try:
return User.objects.get(id=user_id)
except User.DoesNotExist:
raise Http404
def get(self, request, user_id):
user = self.get_obj(user_id)
serializer = UserModelSerializer(user)
return Response(serializer.data)
def put(self, request, user_id):
user = self.get_obj(user_id)
serializer = UserModelSerializer(user, 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, user_id):
user = self.get_obj(user_id)
user.delete()
return Response({'message': '删除成功'})
各种请求分开写,处理逻辑暴露易懂,也容易满足其他开发需求,不过,貌似并非能精简代码啊。
Mixins和GenericAPI类混搭
mixins整合通用了增删改查,配合GenericAPI可进一步精简代码
"""
使用Mixins类和generics类混搭
"""
from rest_framework import mixins
from rest_framework import generics
class UserMixinsList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
"""
处理列表和新增
ListModelMixin: 处理user list
CreateModelMixin: 处理create
GenericAPIView: 继承了APIView
"""
queryset = User.objects.all()
serializer_class = UserModelSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class UserMixinsDetail(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView):
"""
处理单个user, 内置的id参数为`pk`,URL处要注意
RetrieveModelMixin: 查询
UpdateModelMixin: 修改
DestroyModelMixin: 删除
GenericAPIView: 继承了APIview
"""
queryset = User.objects.all()
serializer_class = UserModelSerializer
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)
"""
值得一提的是,CreateModelMixins和内置了一个钩子函数
def perform_update(self, serializer):
serializer.save()
重写这个方法可以在保存数据时做一些其他的操作,比如发邮件。
同样的,其他类也内置了钩子方法,可查看源码。
"""
果然代码精简了不少了,不过看不到业务的操作过程,心里难免有点慌。
最后设置一下url
path('v4/user/', UserMixinsList.as_view()),
path('v4/user/<int:pk>', UserMixinsDetail.as_view()),
当然, 还有更骚气的类,即:
通用类generics.*
DRF将Mixins和GenericAPI预设了一套解决方案,能让代码更精简。
class UserGenricsList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserModelSerializer
class UserGenricsDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = User.objects.all()
serializer_class = UserModelSerializer
6行代码而已,就实现了前面的所有功能。过程已经高度封装,我等小白是万万不敢使用的,万一要自己加点啥逻辑,都不知道该怎么加。
至于视图集,已经封装到眼瞎了,移步大江狗的文章看会更清楚。
总结
需要个性化的,就使用APIView类 需要标准CURD的,就使用generics.*类 另外两个方法不敢想了。
|