文章目录
- 视图
- APIView
- GenericAPIView(将数据库查询、序列化类的定义提取到类变量)
- GenericViewSet(继承ViewSetMixin和GenericAPIView)
- 五大类(List,Create,Retrieve,Update,Destory)
- ModelViewSet(结合五大类)
- 写在最后
视图
APIView
- View,django
- APIView,drf,在请求到来时,新增了:免除csrf、请求封装、版本、认证、权限、限流的功能。
class GenericAPIView(APIView):
pass # 10功能
class GenericViewSet(xxxx.View-2个功能, GenericAPIView):
pass # 5功能能
class UserView(GenericViewSet):
def get(self,request):
pass
APIView
是drf中 “顶层” 的视图类,在他的内部主要实现drf基础的组件的使用,例如:版本、认证、权限、限流等。
# urls.py
from django.urls import path, re_path, include
from app01 import views
urlpatterns = [
path('api/users/', views.UserView.as_view()),
path('api/users/<int:pk>/', views.UserDetailView.as_view()),
]
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
class UserView(APIView):
# 认证、权限、限流等
def get(self, request):
# 业务逻辑:查看列表
return Response({"code": 0, 'data': "..."})
def post(self, request):
# 业务逻辑:新建
return Response({'code': 0, 'data': "..."})
class UserDetailView(APIView):
# 认证、权限、限流等
def get(self, request,pk):
# 业务逻辑:查看某个数据的详细
return Response({"code": 0, 'data': "..."})
def put(self, request,pk):
# 业务逻辑:全部修改
return Response({'code': 0, 'data': "..."})
def patch(self, request,pk):
# 业务逻辑:局部修改
return Response({'code': 0, 'data': "..."})
def delete(self, request,pk):
# 业务逻辑:删除
return Response({'code': 0, 'data': "..."})
GenericAPIView(将数据库查询、序列化类的定义提取到类变量)
GenericAPIView
继承APIView,在APIView的基础上又增加了一些功能。例如:get_queryset
、get_object
等。GenericAPIView会将数据库查询、序列化类提取到类变量中,让后通过get_queryset
、get_object
等方法获取类变量。
GenericAPIView
,将数据库查询、序列化类的定义提取到类变量中,便于后期处理。
实际在开发中一般不会直接继承它,他更多的是担任 中间人
的角色,为子类提供公共功能。
他的子类只需要定义类变量就能轻松的实现相关功能
# urls.py
from django.urls import path, re_path, include
from app01 import views
urlpatterns = [
path('api/users/', views.UserView.as_view()),
path('api/users/<int:pk>/', views.UserDetailView.as_view()),
]
# views.py
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
class UserView(GenericAPIView):
queryset = models.UserInfo.objects.filter(status=True)
serializer_class = 序列化类
def get(self, request):
queryset = self.get_queryset()
ser = self.get_serializer(intance=queryset,many=True)
print(ser.data)
return Response({"code": 0, 'data': "..."})
注意:最大的意义,将数据库查询、序列化类提取到类变量中,后期再提供公共的get/post/put/delete等方法,让开发者只定义类变量,自动实现增删改查。
GenericViewSet(继承ViewSetMixin和GenericAPIView)
GenericViewSet
类中没有定义任何代码,他就是继承 ViewSetMixin
和 GenericAPIView
,也就说他的功能就是将继承的两个类的功能继承到一起。
GenericAPIView
,将数据库查询、序列化类的定义提取到类变量中,便于后期处理。ViewSetMixin
,将 get/post/put/delete 等方法映射到 list、create、retrieve、update、partial_update、destroy方法中,让url分发时直接根据请求的不同直接定位到具体的view视图函数。
# urls.py
from django.urls import path, re_path, include
from app01 import views
urlpatterns = [
path('api/users/', views.UserView.as_view({"get":"list","post":"create"})),
path('api/users/<int:pk>/', views.UserView.as_view({"get":"retrieve","put":"update","patch":"partial_update","delete":"destory"})),
]
# views.py
from rest_framework.viewsets import GenericViewSet
from rest_framework.response import Response
class UserView(GenericViewSet):
# 认证、权限、限流等
queryset = models.UserInfo.objects.filter(status=True)
serializer_class = 序列化类
def list(self, request):
# 业务逻辑:查看列表
queryset = self.get_queryset()
ser = self.get_serializer(intance=queryset,many=True)
print(ser.data)
return Response({"code": 0, 'data': "..."})
def create(self, request):
# 业务逻辑:新建
return Response({'code': 0, 'data': "..."})
def retrieve(self, request,pk):
# 业务逻辑:查看某个数据的详细
return Response({"code": 0, 'data': "..."})
def update(self, request,pk):
# 业务逻辑:全部修改
return Response({'code': 0, 'data': "..."})
def partial_update(self, request,pk):
# 业务逻辑:局部修改
return Response({'code': 0, 'data': "..."})
def destory(self, request,pk):
# 业务逻辑:删除
return Response({'code': 0, 'data': "..."})
注意:开发中一般也很少直接去继承他,因为他也属于是 中间人
类,在原来 GenericAPIView
基础上又增加了一个映射而已。
五大类(List,Create,Retrieve,Update,Destory)
在drf的为我们提供好了5个用于做 增、删、改(含局部修改)、查列表、查单个数据的5个类(需结合 GenericViewSet
使用)。
from rest_framework.mixins import ( ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin,DestroyModelMixin )
还有ModelViewSet类继承了这五个类。
from rest_framework.viewsets import ModelViewSet
# urls.py
from django.urls import path, re_path, include
from app01 import views
urlpatterns = [
path('api/users/', views.UserView.as_view({"get":"list","post":"create"})),
path('api/users/<int:pk>/', views.UserView.as_view({"get":"retrieve","put":"update","patch":"partial_update","delete":"destroy"})),
]
# views.py
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import (
ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin,
DestroyModelMixin, ListModelMixin
)
class UserView(CreateModelMixin,RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin,ListModelMixin,GenericViewSet):
# 认证、权限、限流等
queryset = models.UserInfo.objects.filter(status=True)
serializer_class = 序列化类
在这个5个类中已帮我们写好了 list
、create
、retrieve
、update
、partial_update
、destory
方法,我们只需要在根据写 类变量:queryset、serializer_class即可。
示例1:
# urls.py
from django.urls import path
from app01 import views
urlpatterns = [
path('api/users/', views.UserView.as_view({"get": "list"})),
path('api/users/<int:pk>/', views.UserView.as_view({"get": "retrieve"})),
]
# views.py
from rest_framework import serializers
from rest_framework.viewsets import GenericViewSet
from rest_framework import mixins
from app01 import models
class UserModelSerializer(serializers.ModelSerializer):
level_text = serializers.CharField(
source="get_level_display",
read_only=True
)
extra = serializers.SerializerMethodField(read_only=True)
class Meta:
model = models.UserInfo
fields = ["username", "age", "email", "level_text", "extra"]
def get_extra(self, obj):
return 666
class UserView(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
queryset = models.UserInfo.objects.all()
serializer_class = UserModelSerializer
示例2:
# urls.py
from django.urls import path
from app01 import views
urlpatterns = [
path('api/users/', views.UserView.as_view({"get": "list", "post": "create"})),
path('api/users/<int:pk>/', views.UserView.as_view({"get": "retrieve"})),
]
# views.py
from rest_framework import serializers
from rest_framework.viewsets import GenericViewSet
from rest_framework import mixins
from app01 import models
class UserModelSerializer(serializers.ModelSerializer):
level_text = serializers.CharField(
source="get_level_display",
read_only=True
)
extra = serializers.SerializerMethodField(read_only=True)
class Meta:
model = models.UserInfo
fields = ["username", "age", "email", "level_text", "extra"]
def get_extra(self, obj):
return 666
class UserView(mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.CreateModelMixin, GenericViewSet):
queryset = models.UserInfo.objects.all()
serializer_class = UserModelSerializer
def perform_create(self, serializer):
""" 序列化:对请求的数据校验成功后,执行保存。"""
serializer.save(depart_id=1, password="123")
示例3:
# urls.py
from django.urls import path
from app01 import views
urlpatterns = [
path('api/users/', views.UserView.as_view(
{"get": "list", "post": "create"}
)),
path('api/users/<int:pk>/', views.UserView.as_view(
{"get": "retrieve", "put": "update", "patch": "partial_update", "delete": "destroy"}
)),
]
# views.py
from rest_framework import serializers
from rest_framework.viewsets import GenericViewSet
from rest_framework import mixins
from app01 import models
class UserModelSerializer(serializers.ModelSerializer):
level_text = serializers.CharField(
source="get_level_display",
read_only=True
)
extra = serializers.SerializerMethodField(read_only=True)
class Meta:
model = models.UserInfo
fields = ["username", "age", "email", "level_text", "extra"]
def get_extra(self, obj):
return 666
class UserView(mixins.ListModelMixin,
mixins.RetrieveModelMixin,
mixins.CreateModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
GenericViewSet):
queryset = models.UserInfo.objects.all()
serializer_class = UserModelSerializer
def perform_create(self, serializer):
""" 序列化:对请求的数据校验成功后,执行保存。"""
serializer.save(depart_id=1, password="123")
def perform_update(self, serializer):
serializer.save()
def perform_destroy(self, instance):
instance.delete()
ModelViewSet(结合五大类)
# urls.py
from django.urls import path
from app01 import views
urlpatterns = [
path('api/users/', views.UserView.as_view(
{"get": "list", "post": "create"}
)),
path('api/users/<int:pk>/', views.UserView.as_view(
{"get": "retrieve", "put": "update", "patch": "partial_update", "delete": "destroy"}
)),
]
# views.py
from rest_framework import serializers
from rest_framework.viewsets import ModelViewSet
from app01 import models
class UserModelSerializer(serializers.ModelSerializer):
level_text = serializers.CharField(
source="get_level_display",
read_only=True
)
extra = serializers.SerializerMethodField(read_only=True)
class Meta:
model = models.UserInfo
fields = ["username", "age", "email", "level_text", "extra"]
def get_extra(self, obj):
return 666
class UserView(ModelViewSet):
queryset = models.UserInfo.objects.all()
serializer_class = UserModelSerializer
def perform_create(self, serializer):
""" 序列化:对请求的数据校验成功后,执行保存。"""
serializer.save(depart_id=1, password="123")
在开发过程中使用 五大类
或 ModelViewSet
是比较常见的,并且如果他们内部的某些功能不够用,还可以进行重新某些方法进行扩展。
写在最后
问题:drf中提供了这么多视图,以后那个用的比较多?
答:要根据具体的使用场景对症下药
-
接口与数据库操作无关,直接继承APIView
-
接口背后需要对数据库进行操作,一般:
ModelViewSet
或CreateModelMixin、ListModelMixin...
- 利用钩子自定义功能。 - 重写某个写方法,实现更加完善的功能。
-
根据自己公司的习惯,自定义 :
ModelViewSet
或CreateModelMixin、ListModelMixin...
若有错误与不足请指出,关注DPT一起进步吧!!!