视图集与路由集

发布时间 2023-03-29 17:55:10作者: Hide_凉辰
  •  

     

  •  

     

  • # ViewSet作为APIView的子类,作为视图类的父类
    from rest_framework import status
    from rest_framework.viewsets import ViewSet
    from rest_framework.response import Response
    from FRAMEWORK.models import Student
    from demo.serializers import StudentModelSerializer
    
    """
    最基本的使用ViewSet类
    """
    
    
    class StudentViewSet(ViewSet):
        # 整合了多条数据,单条数据的处理(增删改查与APIView一致)
        # 此时不需要用http请求做方法名,只需要路由指定即可
        def get_all(self, request):
            """获取多条数据"""
            instance = Student.objects.all()
            serializer = StudentModelSerializer(instance=instance, many=True)
            return Response(serializer.data)
    
        def get_one(self, request, pk):
            """获取单条数据"""
            try:
                instance = Student.objects.get(pk=pk)
                serializer = StudentModelSerializer(instance=instance)
                return Response(serializer.data)
            except Student.DoesNotExist:
                return Response({"msg": "当前学生不存在"}, status=status.HTTP_404_NOT_FOUND)
    
    
    """
    使用通用视图集+Mixins混入类
    from rest_framework.viewsets import GenericViewSet
    from rest_framework.mixins import ListModelMixin,CreateModelMixin,UpdateModelMixin,RetrieveModelMixin,DestroyModelMixin
    ViewSet
    GenericViewSet
    万能视图集
    ModelViewSet = GenericViewSet + ListModelMixin + 
                CreateModelMixin + UpdateModelMixin + RetrieveModelMixin + DestroyModelMixin
    只读视图集(获取方案)
    ReadOnlyModelViewSet = GenericViewSet + ListModelMixin + RetrieveModelMixin
    """
    
    from rest_framework.viewsets import ModelViewSet
    
    
    class StudentModelViewSet(ModelViewSet):
        """万能视图集使用"""
        queryset = Student.objects.all()
        serializer_class = StudentModelSerializer

     

  • 路由代码即可合并
  • DefaultRouter和SimpleRouter都是DRF中的路由器类,但它们有一些不同之处。

    SimpleRouter只为视图集中的每个操作(即list,create,retrieve,update,partial_update和destroy)生成一个URL,而DefaultRouter会为视图集中的每个操作(即list,create,retrieve,update,partial_update和destroy)生成一个URL,以及一个额外的URL用于获取视图集中的所有对象。

    因此,如果您只需要标准的CRUD操作,则使用SimpleRouter足以满足您的需求。如果您还需要一个额外的URL来获取视图集中的所有对象,则使用DefaultRouter。

  • from . import views
    from django.urls import path, include, re_path
    from rest_framework.routers import DefaultRouter  # 导入路由集
    from vset.views import StudentModelViewSet
    
    """
    SimpleRouter
    DefaultRouter
    """
    #
    router = DefaultRouter()
    # 注册路由:prefix = 路由前缀;viewset=对应视图;basename=别名
    router.register(prefix="i2", viewset=StudentModelViewSet, basename="i2")
    # urlpatterns += router.urls  # 方式二 :拼接新路由(此句写在urlpatterns后面)
    
    urlpatterns = [
        path(r"i1/", views.StudentViewSet.as_view({"get": "get_all"})),
        path(r"i1/<int:pk>", views.StudentViewSet.as_view({"get": "get_one"})),
    
        re_path(r"^", include(router.urls))  # 方式一:使用include加入新路由
    ]

     

  • 其他视图的使用:需要使用action
  • from rest_framework.viewsets import ModelViewSet
    from rest_framework.decorators import action  # 导入action装饰器
    
    
    class StudentModelViewSet(ModelViewSet):
        """万能视图集使用"""
        queryset = Student.objects.all()
        serializer_class = StudentModelSerializer
    
        # 使用action装饰器添加其他试图的接口
        # methods:列表,填写请求方式,
        # detail:是否加入id参数,为True则需要在视图中添加pk值,为False,则不需要
        # 例如 :http://127.0.0.1:8181/vset/i2/2/login/
        # url_path :访问路径名,不写默认为视图名
        @action(methods=["get", "post"], detail=True, url_path="login")
        def login(self, request, pk):
            # 视图集中[仅限 ViewSet]
            # 通过self.method获得本次客户端的http请求
            # 通过self.action获得本次客户端的视图名
            return Response({"msg": "ok"})