Django REST Framework之视图
Django REST Framework之视图二
一.基于视图集基类ViewSet
上一篇我们说了使用GenericAPIView的视图子类进一步简化,这一篇基于ViewSet进行进一步简化。
继承自APIView
与ViewSetMixin
,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。ViewSet主要通过继承ViewSetMixin来实现在调用as_view()时传入字典(如{‘get’:‘list’})的映射处理工作。
使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中:
- list() 提供一组数据
- retrieve() 提供单个数据
- create() 创建数据
- update() 保存数据
- destory() 删除数据
ViewSet视图集类不再实现get()、post()等方法,而是实现动作 action 如 list() 、create() 等。
1.在Views视图中写如下代码:
from rest_framework.viewsets import ViewSet,GenericViewSet
class Students5View(ViewSet):
# 获取所有数据接口
def get_all_student(self,request): # action
all_data = models.Student.objects.all()
serializer = StudentSerializer(instance=all_data,many=True)
return Response(serializer.data)
# 添加一条记录的接口
def add_student(self,request):
data = request.data
serializer = StudentSerializer(data=data)
if serializer.is_valid():
instance = serializer.save() #instance为添加的新纪录对象
serializer = StudentSerializer(instance=instance)
return Response(serializer.data,status=status.HTTP_201_CREATED)
else:
print(serializer.errors)
def get_one(self,request,pk):
stu_obj = models.Student.objects.get(pk=pk)
serializer = StudentSerializer(instance=stu_obj)
return Response(serializer.data)
2.路由:
urlpatterns = [
path('students5/', views.Students5View.as_view({'get':'get_all_student','post':'add_student'})),
re_path('students5/(?P<pk>\d+)/', views.Students5View.as_view({'get':'get_one'}))
]
二.基于视图集基类GenericViewSet
使用ViewSet通常并不方便,因为list、retrieve、create、update、destory等方法都需要自己编写,而这些方法与前面讲过的Mixin扩展类提供的方法同名,所以我们可以通过继承Mixin扩展类来复用这些方法而无需自己编写。但是Mixin扩展类依赖于GenericAPIView
,所以还需要继承GenericAPIView
。
GenericViewSet就帮助我们完成了这样的继承工作,继承自GenericAPIView
与ViewSetMixin
,在实现了调用as_view()时传入字典(如{'get':'list'}
)的映射处理工作的同时,还提供了GenericAPIView
提供的基础方法,可以直接搭配Mixin扩展类使用。
1.在Views中写入:
from rest_framework.viewsets import ViewSet,GenericViewSet
class Students6View(GenericViewSet):
queryset = models.Student.objects.all()
serializer_class = StudentSerializer
# 获取所有数据接口
def get_all_student(self,request): # action
all_data = self.get_queryset()
serializer = self.get_serializer(instance=all_data,many=True)
return Response(serializer.data)
# 添加一条记录的接口
def add_student(self,request):
data = request.data
serializer = StudentSerializer(data=data)
if serializer.is_valid():
instance = serializer.save() #instance为添加的新纪录对象
serializer = StudentSerializer(instance=instance)
return Response(serializer.data,status=status.HTTP_201_CREATED)
else:
print(serializer.errors)
def get_one(self,request,pk):
stu_obj = models.Student.objects.get(pk=pk)
serializer = StudentSerializer(instance=stu_obj)
return Response(serializer.data)
2.路由
urlpatterns = [
path('students6/', views.Students6View.as_view({'get':'get_all_student','post':'add_student'})),
re_path('students6/(?P<pk>\d+)/', views.Students6View.as_view({'get':'get_one'}))
]
三.基于视图集基类ModelViewSet
继承自GenericViewSet
,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。
1.在Views中写入·:
from rest_framework.viewsets import ViewSet,GenericViewSet
from rest_framework.mixins import ListModelMixin,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin
class Students7View(GenericViewSet,ListModelMixin,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin):
queryset = models.Student.objects.all()
serializer_class = StudentSerializer
# 获取所有数据接口
def get_all_student(self,request): # action
return self.list(request)
# 添加一条记录的接口
def add_student(self,request):
return self.create(request)
def get_one(self,request,pk):
return self.retrieve(request,pk)
def update_one(self,request,pk):
return self.update(request,pk)
def delete_one(self,request,pk):
return self.destroy(request,pk)
2.路由
urlpatterns = [
path('students7/', views.Students7View.as_view({'get':'get_all_student','post':'add_student'})),
re_path('students7/(?P<pk>\d+)/', views.Students7View.as_view({'get':'get_one'}))
]
四.基于视图集基类ModelViewSet
使用ModelViewSet简写上面的继承代码
1.在Views中写入:
from rest_framework.decorators import action
from rest_framework.viewsets import ModelViewSet
class Students8View(ModelViewSet):
queryset = models.Student.objects.all()
serializer_class = StudentSerializer
def login(self,request,pk):
return Response({'msg':'success'})
2.路由:
urlpatterns = [
path('students8/', views.Students8View.as_view({'get':'list','post':'create'})),
re_path('students8/(?P<pk>\d+)/', views.Students8View.as_view({'get':'retrieve','put':'update','delete':'destroy'})),
re_path('students8/login/', views.Students8View.as_view({'get':'login',})),
由于在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。
所以Views中的应该这样写:
from rest_framework.decorators import action
from rest_framework.viewsets import ModelViewSet
class Students8View(ModelViewSet):
queryset = models.Student.objects.all()
serializer_class = StudentSerializer
# 想让defultrouter帮你
@action(methods=['get'], detail=True) #detail=True自动生成带参数的路径,False生成不带参数的路径
def login(self,request,pk):
return Response({'msg':'success'})
对于视图集ViewSet,我们除了可以自己手动指明请求方式与动作action之间的对应关系外,还可以使用Routers来帮助我们快速实现路由信息。
REST framework提供了两个router
- SimpleRouter
- DefaultRouter
(1) 创建router对象,并注册视图集,例如
from rest_framework import routers
router = routers.DefaultRouter()
router.register('dd',views.Students8View)
(2)添加路由数据
可以有两种方式:
方式1 简单一些
urlpatterns = [
...
]
urlpatterns += router.urls
或
方式2
urlpatterns = [
...
url(r'^', include(router.urls))
]
使用路由类给视图集生成了路由地址
from rest_framework.decorators import action
from rest_framework.viewsets import ModelViewSet
class Students8View(ModelViewSet):
queryset = models.Student.objects.all()
serializer_class = StudentSerializer
# 想让defultrouter帮你
@action(methods=['get'], detail=True) #detail=True自动生成带参数的路径,False生成不带参数的路径
def login(self,request,pk):
return Response({'msg':'success'})
路由代码:
from django.urls import path, re_path
from . import views
urlpatterns = [
path('dd/', views.Students8View.as_view({'get':'list','post':'create'})),
re_path('dd/(?P<pk>\d+)/', views.Students8View.as_view({'get':'retrieve','put':'update','delete':'destroy'})),
re_path('dd/login/', views.Students8View.as_view({'get':'login',}))
]
"""使用drf提供路由类router给视图集生成路由列表"""
# 实例化路由类
# drf提供一共提供了两个路由类给我们使用,他们用法一致,功能几乎一样
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
# 注册视图集
router.register("router_stu",views.StudentModelViewSet)
# 把生成的路由列表追加到urlpatterns
print( router.urls )
urlpatterns += router.urls
本文地址:https://blog.csdn.net/qq_45066628/article/details/109267803