Django DRF(三)

1,视图集额外动作
  • 目的: 可以给视图集添加额外的动作(方法)

  • 操作流程:

    • 1, 子路由

       from django.conf.urls import url
       from . import views
       
       urlpatterns = [
           url(r'^books/$',views.BookInfoModelViewSet.as_view({"get":"list","post":"create"})),
           url(r'^books/(?P\d+)/$',views.BookInfoModelViewSet.as_view({"get":"retrieve","put":"update","delete":"destory"})),
       
           url(r'^books/bread/$',views.BookInfoModelViewSet.as_view({"get":"bread_book"})),
       ]
      
    • 2, 类视图

       from django.shortcuts import render
       from rest_framework.viewsets import ModelViewSet
       from booktest.models import BookInfo
       from booktest.serializers import BookInfoModelSerializer
       from rest_framework.response import Response
       
       #1,视图集
       class BookInfoModelViewSet(ModelViewSet):
           queryset = BookInfo.objects.all()
           serializer_class = BookInfoModelSerializer
       
           #1,获取阅读量大于20的书籍
           def bread_book(self,request):
               #1,获取指定书籍
               books = BookInfo.objects.filter(bread__gt=20)
       
               #2,创建序列化器对象
               serializer = self.get_serializer(instance=books,many=True)
       
               #3,返回响应
               return Response(serializer.data)
       
           #2,修改书籍编号为1的, 阅读量为99
       
      
    • 3, 序列化器

      • from rest_framework import serializers
        from booktest.models import BookInfo
        
        #1,模型类序列化器
        class BookInfoModelSerializer(serializers.ModelSerializer):
            class Meta:
                model = BookInfo
                fields = "__all__"
        
2,视图集额外动作,partial
  • 目的: 可以编写额外动作添加参数, 并且更新局部信息

  • 操作流程:

    • 1, 子路由

           url(r'^books/bread/(?P\d+)/$',
            views.BookInfoModelViewSet.as_view({"put":"update_book_bread"})),
       
      
    • 2, 类视图

       class BookInfoModelViewSet(ModelViewSet):
           ...
       
           #2,修改书籍编号为1的, 阅读量为99
           def update_book_bread(self,request,pk):
               #1,获取参数
               book = self.get_object()
               data = request.data
       
               #2,创建序列化器,partial=True可以局部更新
               serializer = self.get_serializer(instance=book,data=data,partial=True)
       
               #3,校验,入库
               serializer.is_valid(raise_exception=True)
               serializer.save()
       
               #4,返回响应
               return Response(serializer.data,status=201)
      
3,路由router
  • 目的: 可以通过DefaultRouter和SimpleRouter两个类来自动生成路由

  • DefautRouter生成路由格式:

    • 特点: 共有三对路由

      • 1, 列表路由
      • 2, 详情路由
      • 3, 根路由
     [
     
     <RegexURLPattern haha-list ^books/$>, 
     <RegexURLPattern haha-list ^books\.(?P<format>[a-z0-9]+)/?$>,
     
     <RegexURLPattern haha-detail ^books/(?P<pk>[^/.]+)/$>, 
     <RegexURLPattern haha-detail ^books/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$>, 
     
     <RegexURLPattern api-root ^$>, 
     <RegexURLPattern api-root ^\.(?P<format>[a-z0-9]+)/?$>
     
     ]
     
    
    • SimpleRouter生成路由格式:

      • 特点: 生成两个路由

        • 1, 列表路由
        • 2, 详情路由
       [
       <RegexURLPattern haha-list ^books/$>, 
       <RegexURLPattern haha-detail ^books/(?P<pk>[^/.]+)/$>
       ]
      
  • 操作流程:

    • 1, 子路由

       from rest_framework.routers import SimpleRouter,DefaultRouter
       #1,创建路由对象
       router = SimpleRouter()
       
       #2,注册视图集
       router.register('books',views.BookInfoModelViewSet,base_name="haha")
       urlpatterns += router.urls
       
       #3,输出结果
       print(urlpatterns)
      
  • 注意点:

    • 1, 使用DRF可以自动根据前端需要的类型, 返回对应格式的数据
    • 2, 请求的时候在请求头中标记, Accept即可
    • 3, 只有视图集,才能自动生成路由
4,装饰action
  • 目的: 可以通过action装饰方法, 自动生成路由

  • 操作流程:

    • 1, 类视图
     from rest_framework.decorators import action
     
     #1,视图集
     class BookInfoModelViewSet(ModelViewSet):
         ...
     
         #1,获取阅读量大于20的书籍
         @action(methods=['GET'],detail=False) #生成路由规则: 前缀/方法名/
         def bread_book(self,request):
             ...
     
         #2,修改书籍编号为1的, 阅读量为99
         @action(methods=["PUT"],detail=True) #生成路由规则: 前缀/{pk}/方法名/
         def update_book_bread(self,request,pk):
             ...
     
    
5,认证Authentication
  • 目的: 可以参考官方文档, 配置认证内容

  • 操作流程:

    • 1, 全局配置(setteings.py)

       # DRF配置信息
       REST_FRAMEWORK = {
           #1,全局认证
           'DEFAULT_AUTHENTICATION_CLASSES': [
               'rest_framework.authentication.BasicAuthentication', #此身份验证方案使用HTTP基本身份验证,用于测试使用
               'rest_framework.authentication.SessionAuthentication', #自己服务器认证用户
           ]
       }
      
    • 2, 局部配置(views.py)

       #1,视图集
       class BookInfoModelViewSet(ModelViewSet):
           ...
       
           #1,局部认证
           authentication_classes = [SessionAuthentication]
      
  • 注意点:

    • 如果配置了全局和局部, 默认使用局部
6,权限Permissions
  • 目的: 可以参考官方文档, 配置权限内容

  • 操作流程:

    • 1, 全局权限配置(settings.py)

       REST_FRAMEWORK = {
           #1,全局认证
           ...
       
           #2,全局权限
           'DEFAULT_PERMISSION_CLASSES': [
               # 'rest_framework.permissions.IsAuthenticated', #普通用户
               # 'rest_framework.permissions.AllowAny', #所有用户
               'rest_framework.permissions.IsAdminUser', #管理员户
           ]
       }
      
    • 2, 局部权限配置(views.py)

       #1,视图集
       class BookInfoModelViewSet(ModelViewSet):
           ...
       
           #1,局部认证
       		...
       
           #2,局部权限
           # permission_classes = [AllowAny]
      
7,限流Throttling
  • 目的: 可以通过配置, 限制不同用户的访问次数

  • 操作流程:

    • 1, 全局配置

       # DRF配置信息
       REST_FRAMEWORK = {
           #1,全局认证
           'DEFAULT_AUTHENTICATION_CLASSES': [
               'rest_framework.authentication.BasicAuthentication', #此身份验证方案使用HTTP基本身份验证,用于测试使用
               'rest_framework.authentication.SessionAuthentication', #自己服务器认证用户
           ],
       
           #2,全局权限
           # 'DEFAULT_PERMISSION_CLASSES': [
           #     # 'rest_framework.permissions.IsAuthenticated', #普通用户
           #     # 'rest_framework.permissions.AllowAny', #所有用户
           #     'rest_framework.permissions.IsAdminUser', #管理员户
           # ],
       
           #3,全局限流
           'DEFAULT_THROTTLE_CLASSES': [
               'rest_framework.throttling.AnonRateThrottle', #匿名用户
               'rest_framework.throttling.UserRateThrottle' # 认证用户
           ],
           'DEFAULT_THROTTLE_RATES': {
               'anon': '2/minute',
               'user': '3/minute'
           }
       }
      
    • 2, 局部配置

       #1,视图集
       class BookInfoModelViewSet(ModelViewSet):
           queryset = BookInfo.objects.all()
           serializer_class = BookInfoModelSerializer
       
           #1,局部认证
           # authentication_classes = [SessionAuthentication]
       
           #2,局部权限
           # permission_classes = [AllowAny]
       
           #3,局部限流
           throttle_classes = [AnonRateThrottle]
      
8, 可选限流
  • 目的: 可以定义可选限流, 用在不同的类视图中

  • 操作流程:

    • 1, 全局定义

       # DRF配置信息
       REST_FRAMEWORK = {
           ...
           #4,可选限流
           'DEFAULT_THROTTLE_CLASSES': [
               'rest_framework.throttling.ScopedRateThrottle',
           ],
           'DEFAULT_THROTTLE_RATES': {
               'downloads': '3/minute',
               'uploads': '5/minute'
           }
       }
      
    • 2, 局部使用

       class TestView(APIView):
           throttle_scope = "uploads"
           def get(self,request):
               return Response("testing....")
      
9,分页Pagination
  • 目的: 可以参考文档, 设置分页返回

  • 操作流程:

    • 1, 全局配置

       REST_FRAMEWORK = {
           ...
         
           #5,全局分页
           'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
           'PAGE_SIZE': 2
       }
      
    • 2, 局部配置

       class BookInfoModelViewSet(ModelViewSet):
           ...
           
           #5,局部分页
           # pagination_class = LimitOffsetPagination # ?limit=100 或者 ?offset=400&limit=100
           pagination_class = PageNumberPagination # ?page=4
       
      
10, 自定义分页类
  • 目的: 可以自定义类, 实现指定分页大小效果

  • 操作流程:

    • 1, 类视图

       
       #自定义分页对象
       class MyPageNumberPagination(PageNumberPagination):
           #1,默认的大小
           page_size = 3
       
           #2,前端可以指定页面大小
           page_size_query_param = 'page_size'
       
           #3,页面的最大大小
           max_page_size = 5
       
       
       #1,视图集
       class BookInfoModelViewSet(ModelViewSet):
          ...
       
           #6,自定义分页对象
           pagination_class = MyPageNumberPagination # ?page=4 或者 ?page=4&page_size=100
       
      
11,过滤Filtering
  • 目的: 可以根据文档配置,进行过滤数据获取

  • 操作流程:

    • 1, 安装扩展django-filters

      • pip install django-filter
    • 2, 注册子应用

       INSTALLED_APPS = [
           ...
           'django_filters',
       ]
      
    • 3, 全局配置

      • REST_FRAMEWORK = {
        		...
            'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']
        }
        
    • 4, 全局配置(views.py)

      • class BookInfoModelViewSet(ModelViewSet):
        	....
          #7,局部过滤
          filter_backends = [DjangoFilterBackend]
          filterset_fields = ['id', 'btitle',"is_delete"]
        
12,排序OrderingFilter
  • 目的: 可以参考文档, 使用指定的字段进行排序

  • 操作流程:

    • 1, 类视图

      • class BookInfoModelViewSet(ModelViewSet):
        	....
              #8,局部排序
            filter_backends = [filters.OrderingFilter] # 导包路径: from rest_framework import filters
            
            ordering_fields = ['id', 'btitle','bread'] #查询格式: ?ordering=-bread,id
        
        
13,异常处理Exceptions
  • 目的: 可以参考文档, 处理程序中的异常信息

  • 操作流程:

    • 1, 定义自定义处理方法(booktest/my_exception.py)

       from rest_framework.views import exception_handler
       from rest_framework.response import Response
       from django.db import DatabaseError
       
       def custom_exception_handler(exc, context):
       
           #1,调用系统方法,处理了APIException的异常,或者其子类异常
           response = exception_handler(exc, context)
       
           #2,判断response是否有值
           if response is not None:
               response.data['status_code'] = response.status_code
           else:
               if isinstance(exc, DatabaseError):
                   response = Response("数据库大出血")
               else:
                   response = Response("其他异常!")
       
           return response
      
    • 2, 全局配置(settings.py)

       REST_FRAMEWORK = {
         	...
           'EXCEPTION_HANDLER': 'booktest.my_exception.custom_exception_handler'
       }
      
    • 3, 测试(views.py)

      • class TestView(APIView):
            # throttle_scope = "uploads"
            def get(self,request):
        
                # raise DatabaseError("DatabaseError!!!")
                raise Exception("报错了!!!")
                # raise APIException("APIException!!!")
                # raise ValidationError("ValidationError!!!")
        
                return Response("testing....")
        
14,接口文档(了解)
  • 目的: 可以参考文档, 配置后端数据的入口文档

  • 操作流程:

    • 1,安装扩展

      • pip install coreapi
    • 2, 根路由

url(**r'^docs/'**, include_docs_urls(title=**'我的API文档'**))
  • 3, 修改字段说明信息

    • 模型类
btitle = models.CharField(max_length=20, verbose_name=**'名称'**,help_text=**"书籍标题"**)
  • 序列化器

     #1,模型类序列化器
     class BookInfoModelSerializer(serializers.ModelSerializer):
         class Meta:
             ...
     
             extra_kwargs = {
                 'bread':{
                     'help_text':"书籍阅读量"
                 }
             }
    
15,vue组件介绍
  • 目的: 知道vue中组件的作用, 和页面的组成
  • 组件:
    • 用来管理页面中的对应的模块
  • 页面:
    • 一个页面可以由各种各样的组件嵌套构成
  • 结构:
    Django DRF(三)_第1张图片
16,vue全局组件
  • 目的: 知道如何定义全局组件,并进行使用

  • 操作流程:

    • 1,组件定义

       <script>
         // 1,定义全局组件
         Vue.component(
           'global_component',
           {
             template:"

      迪丽热巴

      "
      } ) // 2,创建vue对象 var vm = new Vue({ el:"#app" }) </script>
    • 2, 组件使用

            <div id="app">
                
                <global_component>global_component>
                <global_component>global_component>
            div>
      
17,vue局部组件
  • 目的: 知道如何定义局部组件,并进行使用

  • 操作流程:

    • 1,定义局部组件

           <script>
               //1,定义局部组件
               var part_component = {
                   template:"

      古力娜扎

      "
      } //2,创建vue对象, 注册局部组件 var vm = new Vue({ el:"#app", components:{ part1:part_component, part2:{ template:"

      马尔扎哈

      "
      } } }) </script>
    • 2,使用局部组件

           <div id="app">
               
               <part1>part1>
               <part2>part2>
           div>
      
18,全局组件,嵌套局部组件
  • 目的: 知道如何在全局组件中嵌套局部组件,并进行使用

  • 操作流程:

    • 1, 组件的嵌套定义

           <script>
               // 1,定义局部组件
               var part1 = {
                   template:" 大头儿子 "
               }
               var part2 = {
                   template:" 围裙妈妈 "
               }
       
               // 2,全局组件
               Vue.component(
                   'global_component',
                   {
                       template:"
      小头巴巴, ,
      "
      , components:{part1,part2} } ) // 3,创建vue对象 var vm = new Vue({ el:"#app" }) </script>
    • 2, 使用

       <div id="app">
         	<!-- 1,使用组件 -->
       	  <global_component></global_component>
       </div>
      
19,组件中绑定数据data
  • 目的: 可以在全局组件中定义data,并获取数据

  • 操作流程:

    • 1,全局组件定义data

           <script>
               // 1,全局组件
               Vue.component(
                   'global_component',
                   {
                       template:"

      迪丽热巴, {{name}} ,{{age}}

      "
      , data:function(){ return { name:"刷我滴卡", age:13 } } } ) // 2,vm对象 var vm = new Vue({ el:"#app", data: { } }) </script>
    • 2,使用

           <div id="app">
               <global_component>global_component>
           div>
      
20, 分页对象响应返回指定
  • 目的:知道如何去改写, 分页对象的返回数据

  • 操作流程:

    • 1, 类视图(views.py)

       #自定义分页对象
       class MyPageNumberPagination(PageNumberPagination):
           ...
       
           def get_paginated_response(self, data):
               return Response(OrderedDict([
                   ('haha', 'zhangsan'),
                   ('count', self.page.paginator.count),
                   ('next', self.get_next_link()),
                   ('previous', self.get_previous_link()),
                   ('results', data)
               ]))
      

你可能感兴趣的:(DRF,django,python,后端)