Django REST Framework之视图二

  • 一.基于视图集基类ViewSet
  • 二.基于视图集基类GenericViewSet
  • 三.基于视图集基类ModelViewSet
  • 四.基于视图集基类ModelViewSet
    • 由于在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。
    • 对于视图集ViewSet,我们除了可以自己手动指明请求方式与动作action之间的对应关系外,还可以使用Routers来帮助我们快速实现路由信息。

一.基于视图集基类ViewSet

上一篇我们说了使用GenericAPIView的视图子类进一步简化,这一篇基于ViewSet进行进一步简化。

继承自APIViewViewSetMixin,作用也与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就帮助我们完成了这样的继承工作,继承自GenericAPIViewViewSetMixin,在实现了调用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