zoukankan      html  css  js  c++  java
  • def 视图家族

    视图家族:

    基本视图 (APIView):

    --> 主要就是通过视图类APIView,里面的逻辑都需要自己去实现,需要自己写接口 (10大接口)

    子路由:

    from django.conf.urls import url
    from . import views
    urlpatterns = [
        url(r'^books/$', views.BookAPIView.as_view()),
        url(r'^books/(?P<pk>.*)/$', views.BookAPIView.as_view()),
    ]
    

    视图层:

    from rest_framework import views
    from . import models, serializers
    from utils.response import APIResponse
    
    class BookAPIView(views.APIView):
         def post(self, request, *args, **kwargs):
            # 把单增也转换为群增
            request_data = request.data
            if isinstance(request_data, dict):
                data = [request_data, ]
            elif isinstance(request, list):
                data = request_data
            else:
                return APIView(1, '数据格式有误')
            
            book_ser = serializers.BookV2ModelSerializer(data=data, many=True)
            if book_ser.is_valid():
                book_obj_list = book_ser.save()
                results = serializers.BookV2ModelSerializer(book_obj_list, many=True).data
                return APIResponse(0, 'ok', results=results)
            else:
                return APIResponse(1, '添加失败', results=book_ser.errors)
    

    视图工具类 (mixins):

    介绍:

    RetrieveModelMixin:		retrieve 方法实现了获取一个对象  (单查)
    
    ListModelMixin:			list方法实现了获取多个对象  	 (群查)
    
    CreateModelMixin:		create方法实现了增加一个对象	  (单增)
    
    UpdateModelMixin:		update方法实现了单整体更新,      (put 改)
    					    partial_update实现了单局部更新	 (patch 改)
    
    DestroyModelMixin:		destory方法实现了单独删除		(单删)
    
    -----》 一般结合generics工具视图使用
    
        继承工具类可以简化请求函数的实现体,但是必须继承GenericAPIView,需要GenericAPIView类提供的几个类属性和方法
    
        工具类的工具方法返回值都是Response类型对象,如果要格式化数据格式再返回给前台,可以通过 response.data 拿到工具方法返回的Response类型对象的响应数据
    

    子路由:

    urlpatterns = [
       	url(r'^v3/books/$', views.BookMixinGenericAPIView.as_view()),
        url(r'^v3/books/(?P<pk>.*)/$', views.BookMixinGenericAPIView.as_view()),
    ]
    

    视图层:

    from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin
    class BookMixinGenericAPIView(ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, GenericAPIView):
        queryset = models.Book.objects.filter(is_delete=False)
        serializer_class = serializers.BookModelSerializer
    
        def get(self, request, *args, **kwargs):
            if 'pk' in kwargs:
                response = self.retrieve(request, *args, **kwargs)
            else:
                # mixins提供的list方法的响应对象是Response,想将该对象格式化为APIResponse
                response = self.list(request, *args, **kwargs)
            # response的数据都存放在response.data中
            return APIResponse(results=response.data)
    
        def post(self, request, *args, **kwargs):
            response = self.create(request, *args, **kwargs)
            return APIResponse(results=response.data)
    
        def put(self, request, *args, **kwargs):
            response = self.update(request, *args, **kwargs)
            return APIResponse(results=response.data)
    
        def patch(self, request, *args, **kwargs):
            response = self.partial_update(request, *args, **kwargs)
            return APIResponse(results=response.data)
    

    工具视图 (generics):

    介绍:

    GenericAPIView:
    
    GenericAPIView,是generics家族的基类,主要帮我们把qureyset和serializer_class封装成了属性
    
     1)工具视图都是GenericAPIView的子类,且不同的子类继承了不听的工具类,重写了请求方法
     2)工具视图的功能如果直接可以满足需求,只需要继承工具视图,提供queryset与serializer_class即可
    

    GenericAPIView基类:

    GenericAPIView是继承APIView的,使用完全兼容APIView
    
    重点:GenericAPIView在APIView基础上完成了哪些事
        1)get_queryset():从类属性queryset中获得model的queryset数据
        2)get_object():从类属性queryset中获得model的queryset数据,再通过有名分组pk确定唯一操作对象
        3)get_serializer():从类属性serializer_class中获得serializer的序列化类
    

    视图层:

    from rest_framework.generics import GenericAPIView
    class BookGenericAPIView(GenericAPIView):
        
        queryset = models.Book.objects.filter(is_delete=False)
        serializer_class = serializers.BookModelSerializer
        # 自定义主键的 有名分组 名
        lookup_field = 'pk'      			 		# 源码内与之对应
        # 群取
        # def get(self, request, *args, **kwargs):
        #     book_query = self.get_queryset()
        #     book_ser = self.get_serializer(book_query, many=True)
        #     book_data = book_ser.data
        #     return APIResponse(results=book_data)
    
        # 单取
        def get(self, request, *args, **kwargs):
            book_query = self.get_object()
            book_ser = self.get_serializer(book_query)
            book_data = book_ser.data
            return APIResponse(results=book_data)
    
    注意: 不能同时出现单 | 群取
    
    
    from rest_framework.generics import ListCreateAPIView, UpdateAPIView
    class BookListCreatePIView(ListCreateAPIView, UpdateAPIView):
        queryset = models.Book.objects.filter(is_delete=False)
        serializer_class = serializers.BookModelSerializer
    

    视图集 (viewsets):

    子路由:

    1)视图集都是优先继承ViewSetMixin类,再继承一个视图类(GenericAPIView或APIView)
          GenericViewSet、ViewSet
            
    2)ViewSetMixin提供了重写的as_view()方法,继承视图集的视图类,配置路由时调用as_view()必须传入 请求名-函数名 映射关系字典
    
    eg: url(r'^v5/books/$', views.BookGenericViewSet.as_view({'get': 'my_get_list'})),
    表示get请求会交给my_get_list视图函数处理
    
    
    urlpatterns = [
        url(r'^v5/books/$', views.BookGenericViewSet.as_view({'get': 'my_get_list'})),
        url(r'^v5/books/(?P<pk>.*)/$', views.BookGenericViewSet.as_view({'get': 'my_get_obj'})),
    ]
    

    视图层:

    使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中:
    
        list() 提供一组数据
        retrieve() 提供单个数据
        create() 创建数据
        update() 保存数据
        destory() 删除数据
        ViewSet视图集类不再实现get()、post()等方法,而是实现动作action如 list() 、create() 等
    
    视图集只在使用as_view()方法的时候,才会将action动作与具体请求方式对应上。
    
    
    
    from rest_framework.viewsets import GenericViewSet
    from rest_framework import mixins
    class BookGenericViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, GenericViewSet):
        queryset = models.Book.objects.filter(is_delete=False)
        serializer_class = serializers.BookModelSerializer
    
        def my_get_list(self, request, *args, **kwargs):
            return self.list(request, *args, **kwargs)
    
        def my_get_obj(self, request, *args, **kwargs):
            return self.retrieve(request, *args, **kwargs)
    
    设置路由时:
        urlpatterns = [
        url(r'^books/$', BookInfoViewSet.as_view({'get':'list'}),
        url(r'^books/(?P<pk>d+)/$', BookInfoViewSet.as_view({'get': 'retrieve'})
    ]
    

    action属性:

    在视图集中,我们可以通过action对象属性来获取当前请求视图集时的action动作是哪个
    
    def get_serializer_class(self):
        if self.action == 'create':
            return OrderCommitSerializer
        else:
            return OrderDataSerializer
    

    常用视图集父类:

    (1)ViewSet
    继承自APIView,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。
    
    在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。
    
    (2)GenericViewSet
    继承自GenericAPIView,作用也与GenericAPIVIew类似,提供了get_object、get_queryset等方法便于列表视图与详情信息视图的开发。
    
    (3)ModelViewSet
    继承自GenericAPIVIew,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。
    
    (4)ReadOnlyModelViewSet
    继承自GenericAPIVIew,同时包括了ListModelMixin、RetrieveModelMixin
    
    添加自定义动作需要使用rest_framework.decorators.action装饰器。
    
    以action装饰器装饰的方法名会作为action动作名,与list、retrieve等同。
    
    action装饰器可以接收两个参数:
    
    methods: 该action支持的请求方式,列表传递
    detail: 表示是action中要处理的是否是视图资源的对象(即是否通过url路径获取主键)
    True 表示使用通过URL获取的主键对应的数据对象
    False 表示不使用URL获取主键
    
    
      @action(methods=['get'], detail=False)
        def latest(self, request):
            """
            返回最新的图书信息
            """
            book = BookInfo.objects.latest('id')
            serializer = self.get_serializer(book)
            return Response(serializer.data)
    
        # detail为True,表示要处理具体与pk主键对应的BookInfo对象
        @action(methods=['put'], detail=True)
        def read(self, request, pk):
            """
            修改图书的阅读量数据
            """
            book = self.get_object()
            book.bread = request.data.get('read')
            book.save()
            serializer = self.get_serializer(book)
            return Response(serializer.data)
        
        
    # urls.py
    
        
    urlpatterns = [
    	url(r'^books/(?P<pk>d+)/$', views.BookInfoViewSet.as_view({'get': 'retrieve'})),
        url(r'^books/(?P<pk>d+)/read/$', views.BookInfoViewSet.as_view({'put': 'read'})),
    ]
    

    路由Router:

    路由Router
        对于视图集ViewSet,我们除了可以自己手动指明请求方式与动作action之间的对应关系外,还可以使用Routers来帮助我们快速实现路由信息。
    
    REST framework提供了两个router:
    
        SimpleRouter
        DefaultRouter
    
    创建router 对象:
    	from rest_framework import routers
    
        router = routers.SimpleRouter()
        router.register(r'books', BookInfoViewSet, base_name='book')
    
    
    register(prefix, viewset, base_name)
    
        prefix 该视图集的路由前缀
        viewset 视图集
        base_name 路由名称的前缀
    
    注意: prtfix : 前缀后不用加换行符,会自动加
    

    添加路由数据方式:

    # 方式一:
    urlpatterns = [
        ...
    ]
    urlpatterns += router.urls
    
    #方式二:
    urlpatterns = [
        ...
        url(r'^', include(router.urls))
    ]
    
    
    #2.视图集中包含附加action:
    
    class BookInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
        queryset = BookInfo.objects.all()
        serializer_class = BookInfoSerializer
    
        @action(methods=['get'], detail=False)
        def latest(self, request):
            ...
    
        @action(methods=['put'], detail=True)
        def read(self, request, pk):
            ...
    
        DefaultRouter与SimpleRouter的区别是,DefaultRouter会多附带一个默认的API根视图,返回一个包含所有列表视图的超链接响应数据
    

    路由router形成URL的方式:

    SimpleRouter:

    DefaultRouter:

  • 相关阅读:
    js加密解密 base64
    Server2003上部署Excel服务器
    SQL 2000和SQL 2005服务端口查看或修改
    IIS6.0的安装
    VSS 2005 配置(含录像)
    SQL2005开启远程连接功能
    SQL 2005 SP3在小内存计算机中安装(最佳方案)
    windows防火墙的使用
    Server2003上部署Excel服务器
    通过连接实例解读TCP/IP协议
  • 原文地址:https://www.cnblogs.com/shaozheng/p/12121277.html
Copyright © 2011-2022 走看看