• DRF教程4-视图集和路由类


    rest框架包括一个处理viewset的抽象,允许开发人员集中精力处理api交互和建模,url构造都根据常见方式自动处理。

    ViewSet类 几乎和VIew类一样,不过它提供read,update这样的操作,而不是get,put。

    Refactoring to use ViewSets

    现在来重构之前的view代码。首先把CourseList和CourseDetail重构为一个简单的CourseViewSet。

    from rest_framework import viewsets
    
    from .models import Course
    from .serializer import CourseSerializer
    
    
    class CourseViewSet(viewsets.ModelViewSet):
        """
        This viewset automatically provides `list`, `create`, `retrieve`,
        `update` and `destroy` actions.
        """
        queryset = Course.objects.all()
        serializer_class = CourseSerializer
    #继承自ModelViewSet类,就是说已经自带了视图集的五个action
    #就是说向外暴露了五个操作接口
    

      

    有时候只需要 提供只读信息,那么就只能list和retrieve,就需要只读接口

    from rest_framework import viewsets
    
    from .models import UserProfile
    from .serializer import UserProfileSerializer
    
    
    class UserProfileViewSet(viewsets.ReadOnlyModelViewSet):
        """
        retrieve : return a user info
        list: return all the user info
        """
        queryset = UserProfile.objects.all()
        serializer_class = UserProfileSerializer
    #只向外暴露retrieve和list接口
    

      

    自定义接口

    ModelViewSet提供了全部接口,ReadOnlyModelViewSet提供了list和get接口,

    接口肯定要把不必要的接口类型禁用,比如delete。

    如果需要delete之外的全部接口,就需要重写视图类

    class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
        """
        The GenericViewSet class does not provide any actions by default,
        but does include the base set of generic view behavior, such as
        the `get_object` and `get_queryset` methods.
        """
        pass
    
    class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
                               mixins.ListModelMixin,
                               GenericViewSet):
        """
        A viewset that provides default `list()` and `retrieve()` actions.
        """
        pass
    
    
    class ModelViewSet(mixins.CreateModelMixin,
                       mixins.RetrieveModelMixin,
                       mixins.UpdateModelMixin,
                       mixins.DestroyModelMixin,
                       mixins.ListModelMixin,
                       GenericViewSet):
        """
        A viewset that provides default `create()`, `retrieve()`, `update()`,
        `partial_update()`, `destroy()` and `list()` actions.
        """
        pass
    #阅读viewsets的源码,可知本质就是把mixins的几个子类引入进来
    #不同接口引入不同的类
    

      

    #先引入相关类
    from rest_framework import mixins
    from rest_framework.viewsets import GenericViewSet
    
    
    class GameGroupViewSet(mixins.RetrieveModelMixin,
                            mixins.UpdateModelMixin,
                            mixins.ListModelMixin,
                           GenericViewSet):
        """
        retrieve:
            返回指定信息
        list:
            返回列表
        update:
            更新信息
        partial_update:
            更新部分字段
        """
        queryset = GameGroup.objects.all()
        serializer_class = GameGroupSerializer
    #重写视图类
    

      

    重写get_queryset

    在视图类中,queryset属性一般就是model.objects.all(),但很多情况下是要对数据进行筛选修改的,所以就需要重新

    class SvrFormalViewSet(viewsets.ReadOnlyModelViewSet):
        """
        retrieve:
            返回指定信息
        list:
            返回列表
        """
    
        serializer_class = SvrSerializer
    
        def get_queryset(self):
    
            q = ~Q(sid__in = [5000,5012,5020])   #去掉测试区
            appids = []
    
            _appids = list(Svrconfig.objects.filter(q).values('id')) #嵌套字典的列表
            for appid in _appids:       #转化appid的列表
                appids.append(appid['id'])
    
            details = Svr.objects.filter(appid__in = appids)
    
            return details
    #得到的查询集不再all(),而是修改过的details
    

      

    Binding ViewSets to URLs explicitly

    viewset只是带进了一组action,比如list,create等。

    在url中,把http方法绑定到相关的动作上。请求get,就路由到list,请求post action,就请求道create action。

    courseList = views.CourseViewSet.as_view({
        "get": "list",
        "post": "create"
    })
    
    courseDetail = views.CourseViewSet.as_view({
        "get": "retrieve",
        "put": "update",
        "delete": "destroy"
    })
    
    urlpatterns = [
        path('admin/', xadmin.site.urls),
        path('course/', courseList,name='course_list'),
        path('course/<int:pk>/', courseDetail ,name='course_detail'),
    ]
    urlpatterns = format_suffix_patterns(urlpatterns)
    

      

    Using Routers

    使用routers,需要做的是使用路由器注册适当的视图集,而其余的资源连接可以使用Router类自动处理。

    可见,course资源相关的,只需要一个url,其他router会自动处理。

    可选参数,base_name:   用来生成urls名字,如果viewset中没有包含queryset, base_name一定要有

    from django.urls import path,include
    from rest_framework.routers import DefaultRouter
    from courses.views import CourseViewSet
    import xadmin
    
    router = DefaultRouter()
    router.register('course', CourseViewSet,base_name='course')
    
    urlpatterns = [
        path('admin/', xadmin.site.urls),
        path('', include(router.urls)),
    ]
    #不再需要在app里创建urls文件,只需要在项目目录下将资源的视图集注册到router。
    

      

  • 相关阅读:
    jQuery对表单的操作
    js-工厂模式
    js中call、apply、bind的区别
    js实现重载和重写
    js封装/继承/多态
    变量的解构赋值
    var & let & const 的区别
    jQuery之animate中的queue
    jQuery之动画
    .trigger
  • 原文地址:https://www.cnblogs.com/jabbok/p/10563876.html
Copyright © 2020-2023  润新知