偏移分頁-遊標(加密)分頁-自定義過濾器-第三方過濾器插件(django-filter)

複習

"""
一、drf-jwt簽發與校驗源碼
    簽發token的請求 - 登陸請求 - ObtainJSONWebToken - post - 將帳號密碼丟給序列化類處理 - 獲得user、token => 序列化類的全局鉤子
    要訪問須要認證的視圖類 - 訪問前須要經過認證組件與權限組件的校驗 - jwt認證和是否登陸權限 - 給認證組件提供帶有token請求頭的請求,將token解析出user,返回 (user, token) => drf-jwt框架的jwt認證組件的認證方法
    
二、多方式登陸(手動簽發)
    簡單:從request拿帳號密碼 - 數據庫查詢獲得user - payload - token - 返回
    複雜:
        視圖:將帳號密碼等信息丟該序列化類 - 從序列化對象中拿user、token - 返回
        序列化:定義字段接收要反序列化的數據 - 全局鉤子校驗數據獲得user,並簽發token - user、token保存在實例化對象中
    
三、自定義jwt認證規則(手動校驗)
    實現:自定義認證類,繼承BaseJSONWebTokenAuthentication - 自定義token反爬小策略,從請求頭中獲取並拋出設置的鹽後的token
    

前提:羣查接口
四、搜索組件
    1)視圖類:filter_backends = [SearchFilter]
    2)視圖類:search_fields = ['name', 'price']
    3)接口:/cars/?search=...  | eg: /cars/?search=1

五、排序組件
    1)視圖類:filter_backends = [OrderingFilter]
    2)視圖類:search_fields = ['pk', 'price']
    3)接口:/cars/?ordering=... |  eg: /cars/?ordering=-price,pk

六、基礎分頁組件
    1)自定義分頁類繼承drf分頁類,將必要參數賦值
    2)視圖類: pagination_class = pagenations.MyPageNumberPagination
    3)接口:/cars/
"""

drf偏移分頁組件

pahenations.py
from rest_framework.pagination import LimitOffsetPagination
class MyLimitOffsetPagination(LimitOffsetPagination):
    # ?offset=從頭偏移的條數&limit=要顯示的條數
    limit_query_param = 'limit'
    offset_query_param = 'offset'
    # ?不傳offset和limit默認顯示前3條,只設置offset就是從偏移位日後再顯示3條
    default_limit = 3
    # ?limit能夠自定義一頁顯示的最大條數
    max_limit = 5

    # 只使用limit結合ordering能夠實現排行前幾或後幾
    # ?ordering=-price&limit=2  => 價格前2
views.py
from rest_framework.generics import ListAPIView

class CarListAPIView(ListAPIView):
    # 若是queryset沒有過濾條件,就必須 .all(),否則分頁會出問題
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
    
    # 分頁組件 - 給視圖類配置分頁類便可 - 分頁類須要自定義,繼承drf提供的分頁類便可
    pagination_class = pagenations.MyLimitOffsetPagination

drf遊標分頁組件(瞭解)

pahenations.py
# 注:必須基於排序規則下進行分頁
# 1)若是接口配置了OrderingFilter過濾器,那麼url中必須傳ordering
# 1)若是接口沒有配置OrderingFilter過濾器,必定要在分頁類中聲明ordering按某個字段進行默認排序
from rest_framework.pagination import CursorPagination
class MyCursorPagination(CursorPagination):
    cursor_query_param = 'cursor'
    page_size = 3
    page_size_query_param = 'page_size'
    max_page_size = 5
    ordering = '-pk'
views.py
from rest_framework.generics import ListAPIView

class CarListAPIView(ListAPIView):
    # 若是queryset沒有過濾條件,就必須 .all(),否則分頁會出問題
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
    
    # 分頁組件 - 給視圖類配置分頁類便可 - 分頁類須要自定義,繼承drf提供的分頁類便可
    pagination_class = pagenations.MyCursorPagination

自定義過濾器

filters.py
# 自定義過濾器,接口:?limit=顯示的條數
class LimitFilter:
    def filter_queryset(self, request, queryset, view):
        # 前臺固定用 ?limit=... 傳遞過濾參數
        limit = request.query_params.get('limit')
        if limit:
            limit = int(limit)
            return queryset[:limit]
        return queryset
views.py
from rest_framework.generics import ListAPIView

class CarListAPIView(ListAPIView):
    # 若是queryset沒有過濾條件,就必須 .all(),否則分頁會出問題
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
    
    # 局部配置 過濾類 們(全局配置用DEFAULT_FILTER_BACKENDS)
    filter_backends = [LimitFilter]

過濾器插件:django-filter

安裝
>: pip3 install django-filter
過濾條件層:自定義api/filters.py
# django-filter插件過濾器類
from django_filters.rest_framework.filterset import FilterSet
from . import models

# 自定義過濾字段
from django_filters import filters
class CarFilterSet(FilterSet):
    min_price = filters.NumberFilter(field_name='price', lookup_expr='gte')
    max_price = filters.NumberFilter(field_name='price', lookup_expr='lte')
    class Meta:
        model = models.Car
        fields = ['brand', 'min_price', 'max_price']
        # brand是model中存在的字段,通常都是能夠用於分組的字段
        # min_price、max_price是自定義字段,須要本身自定義過濾條件
視圖層:views.py
# django-filter插件過濾器
from django_filters.rest_framework import DjangoFilterBackend
from .filters import CarFilterSet

class CarListAPIView(ListAPIView):
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
    
    # 局部配置 過濾類 們(全局配置用DEFAULT_FILTER_BACKENDS)
    filter_backends = [DjangoFilterBackend]
    
    # django-filter過濾器插件使用
    filter_class = CarFilterSet
    # 接口:?brand=...&min_price=...&max_price=...
    # eg:?brand=寶馬&min_price=5&max_price=10 => 5~10間的寶馬牌汽車
相關文章
相關標籤/搜索