DRF學習day3隨堂筆記


前天復習

  • write_only:只寫;只進行反序列化,不進行序列化
  • read_only:只讀;只進行序列化,不進行反序列化

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<pk>\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<pk>\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, 根路由 (什么參數也不用傳)

    • from rest_framework.routers import SimpleRouter,DefaultRouter
      #1,創建路由對象
      router = DefaultRouter()
      
      #2,注冊視圖集
      router.register('books',views.BookInfoModelViewSet,basename="haha")
      urlpatterns += router.urls
      
      #3,輸出結果
      print(urlpatterns)
      
      
      [
      
      <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, 詳情路由
  • 操作流程:

    • 1, 子路由

      • from rest_framework.routers import SimpleRouter,DefaultRouter
        #1,創建路由對象
        router = SimpleRouter()
        
        #2,注冊視圖集
        router.register('books',views.BookInfoModelViewSet,basename="haha")
        urlpatterns += router.urls
        
        #3,輸出結果
        print(urlpatterns)
        
        [
        <RegexURLPattern haha-list ^books/$>, 
        <RegexURLPattern haha-detail ^books/(?P<pk>[^/.]+)/$>
        ]
        
  • 注意點:

    • 1, 使用DRF可以自動根據前端需要的類型, 返回對應格式的數據
    • 2, 請求的時候在請求頭中標記, Accept即可
    • 3, 只有視圖集,才能自動生成路由

4,裝飾action

  • 目的: 可以通過action裝飾方法, 自動生成路由

  • 操作流程:

    • 1, 類視圖

    • from rest_framework.decorators import action
      
      #1,視圖集
      class BookInfoModelViewSet(ModelViewSet):
          ...
      
          # 使用路由router自動生成路由后 不會處理我們自己定義的類,需要設置action
          @action(methods=['GET'], detail=False)  # 生成路由規則: 前綴/方法名/  detail處理是否需要攜帶參數
          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',#設置匿名用戶(未授權用戶) 每分鍾只能訪問2次
                'user': '3/minute'# 設置認證用戶每分鍾只能訪問3次
            },
        }
        
    • 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(一頁顯示100條) 或者 ?offset=2(從第2條數據開始顯示)&limit=100
            pagination_class = PageNumberPagination # ?page=4(指定顯示頁數) 或者 ?page=4&page_size=20(指定頁顯示數據的數量)
        
        

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=20(指定頁顯示數據的數量)
        
        

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"]
          
          http://127.0.0.1:8000/books/?id=1
          http://127.0.0.1:8000/books/?btitle=射雕英雄傳
          http://127.0.0.1:8000/books/?is_delete=False
        

12,排序OrderingFilter

  • 目的: 可以參考文檔, 使用指定的字段進行排序

  • 操作流程:

    • 1, 類視圖

      • class BookInfoModelViewSet(ModelViewSet):
        	....
              #8,局部排序
            filter_backends = [filters.OrderingFilter] # 導包路徑: from rest_framework import filters
            
            ordering_fields = ['id', 'btitle','bread'] #查詢格式: ?ordering=-bread,id 傳什么,就可以按照什么排序
            
            http://127.0.0.1:8000/books/?ordering=id 依據id正序排序
            http://127.0.0.1:8000/books/?ordering=-id 依據id逆序排序   
            
            #可以傳兩個參數 依據btitle排序,相同的btitle再根據id排序  
            http://127.0.0.1:8000/books/?offset=3&ordering=btitle,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
    • 全局配置(settings.py)

      REST_FRAMEWORK = {
        	...
          'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
      }
      
    • 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中組件的作用, 和頁面的組成
  • 組件:
    • 用來管理頁面中的對應的模塊
  • 頁面:
    • 一個頁面可以由各種各樣的組件嵌套構成
  • 結構:
    • image-20191220154102038

16,vue全局組件

  • 目的: 知道如何定義全局組件,並進行使用

  • 操作流程:

    • 1,組件定義

      • <script>
          // 1,定義全局組件
          Vue.component(
            'global_component',
            {
              template:"<h1>迪麗熱巴</h1>"
            }
          )
        
          // 2,創建vue對象
          var vm = new Vue({
            el:"#app"
          })
        </script>
        
    • 2, 組件使用

      •     <div id="app">
                <!-- 1,使用組件 -->
                <global_component></global_component>
                <global_component></global_component>
            </div>
        

17,vue局部組件

  • 目的: 知道如何定義局部組件,並進行使用

  • 操作流程:

    • 1,定義局部組件

      •     <script>
                //1,定義局部組件
                var part_component = {
                    template:"<h1>古力娜扎</h1>"
                }
        
                //2,創建vue對象, 注冊局部組件
                var vm = new Vue({
                    el:"#app",
                    components:{
                        part1:part_component,
                        part2:{
                            template:"<h1>馬爾扎哈</h1>"
                        }
                    }
                })
        
            </script>
        
    • 2,使用局部組件

      •     <div id="app">
                <!-- 1,使用局部組件 -->
                <part1></part1>
                <part2></part2>
            </div>
        

18,全局組件,嵌套局部組件

  • 目的: 知道如何在全局組件中嵌套局部組件,並進行使用

  • 操作流程:

    • 1, 組件的嵌套定義

      •     <script>
                // 1,定義局部組件
                var part1 = {
                    template:"<span> 大頭兒子 </span>"
                }
                var part2 = {
                    template:"<span> 圍裙媽媽 </span>"
                }
        
                // 2,全局組件
                Vue.component(
                    'global_component',
                    {
                        template:"<div> 小頭巴巴, <part1></part1>, <part2></part2></div>",
                        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:"<h1>迪麗熱巴, {{name}} ,{{age}} </h1>",
                        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)
                ]))
        


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM