drf 過濾器(條件查詢 排序 )分頁器


drf 過濾器(條件查詢 排序 )分頁器

目錄

一、群查接口各種篩選組件

數據准備

img

models.py

img View Code

admin.py 注冊
admin.site.register(models.Car)
serializers.py
class CarModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Car
        fields = ['name', 'price', 'brand']
views.py
# Car的群查接口
from rest_framework.generics import ListAPIView

class CarListAPIView(ListAPIView):
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
urls.py
url(r'^cars/$', views.CarListAPIView.as_view()),

1.drf 搜索 過濾組件

views.py
from rest_framework.generics import ListAPIView

# 第一步:drf的SearchFilter - 搜索過濾
from rest_framework.filters import SearchFilter

class CarListAPIView(ListAPIView):
    queryset = models.Car.objects  # 固定的兩個東西,源碼內部默認為None
    serializer_class = serializers.CarModelSerializer

    # 第二步:局部配置 過濾類 們(全局配置用DEFAULT_FILTER_BACKENDS)
    filter_backends = [SearchFilter]

    # 第三步:SearchFilter過濾類依賴的過濾條件 => 接口:/cars/?search=...
    search_fields = ['name', 'price']
    # eg:/cars/?search=1,name和price中包含1的數據都會被查詢出

2. drf 排序 過濾組件

views.py
from rest_framework.generics import ListAPIView

# 第一步:drf的OrderingFilter - 排序過濾
from rest_framework.filters import OrderingFilter

class CarListAPIView(ListAPIView):
    queryset = models.Car.objects
    serializer_class = serializers.CarModelSerializer

    # 第二步:局部配置 過濾類 們(全局配置用DEFAULT_FILTER_BACKENDS)
    filter_backends = [OrderingFilter]

    # 第三步:OrderingFilter過濾類依賴的過濾條件 => 接口:/cars/?ordering=...
    ordering_fields = ['pk', 'price']
    # eg:/cars/?ordering=-price,pk,先按price降序,如果出現price相同,再按pk升序

3. drf 基礎分頁組件

api / pahenations.py
from rest_framework.pagination import PageNumberPagination

class MyPageNumberPagination(PageNumberPagination):
    # ?page=1,這個就是url中的key,
    page_query_param = 'page'
    # ?page=1 不傳自定義條數時默認一頁顯示的條數,可以通過下面的參數設置自定義
    page_size = 3
    # ?page=2&page_size=3 第二頁每頁顯示3條數據 用戶自定義一頁顯示的條數
    page_size_query_param = 'page_size'
    # 用戶自定義一頁顯示的條數最大限制:數值超過5也只顯示5條
    max_page_size = 5
views.py
from rest_framework.generics import ListAPIView

class CarListAPIView(ListAPIView):
    # 如果queryset沒有過濾條件,就必須 .all(),不然分頁會出問題,上面搜索和排序不需要all是因為人家已經過濾過了
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
    
    # 分頁組件 - 給視圖類配置分頁類即可 - 分頁類需要自定義,繼承drf提供的分頁類即可
    pagination_class = pagenations.MyPageNumberPagination

img

4. 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可以實現排行前幾或后幾,后面我們會自定義limit過濾器就不需要基於分頁了
    # ?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

5. 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'  # 按照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

6. 自定義 limit 過濾器

我不想借助分頁,我就想自定義一個條數過濾器,他可以對各過濾組件過濾結果進行顯示限制

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
    # eg:/cars/?ordering=-price,pk&limit=3,先按price降序,如果出現price相同,再按pk升序,篩選結果顯示3條
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]

7. 過濾器插件: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')  # gte lte 源碼里面有,表示最大最小值
    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間的寶馬牌汽車


免責聲明!

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



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