欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Django REST Framework之视图

程序员文章站 2022-07-02 11:25:09
Django REST Framework之视图二一.基于视图集基类ViewSet二.基于视图集基类GenericViewSet三.基于视图集基类ModelViewSet四.基于视图集基类ModelViewSet由于在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。对于视图集ViewSet,我们除了可以自己手动指明请求方式与动作action之间的对应关系外,还可以使用Routers来帮助我们快速实现路由信息。一.基于视图集基类ViewSet上一篇我们说了使用Gene...

一.基于视图集基类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