1. 程式人生 > 實用技巧 >Django:drf過濾、搜尋、排序功能

Django:drf過濾、搜尋、排序功能

過濾功能實現

1.get_query_set方法過濾

編輯blogs目錄下的views.py,新增get_queryset方法

class ArticleListViewset(mixins.ListModelMixin,
                         mixins.CreateModelMixin,
                         viewsets.GenericViewSet):
    serializer_class = ArticleSerializer
    pagination_class = StandardResultsSetPagination
    
def get_queryset(self): queryset = Article.objects.all() click_num = self.request.query_params.get('click', 0) if click_num: queryset = queryset.filter(click_num__gte=30) return queryset

在瀏覽器輸入http://localhost:8000/api/v1/articles/?click=50,click代表引數值過濾了大於50點選數的文章。但是當過濾引數多的時候此過濾方法寫起來比較麻煩

2.django-filters方法過濾

pip install django-filter 安裝django-filter

在settings.py註冊配置django-filters,在REST_FRAMEWORK 加上過濾器會對全域性生效,如果只針對特定檢視可以單獨在view裡面加

①settings.py全域性過濾器

編輯settings.py

# 註冊新增過濾模組
INSTALLED_APPS = [
    ...,
    'django_filters',
    ...,
]
# 新增過濾器,全域性生效
REST_FRAMEWORK = {
    ...,
    'DEFAULT_FILTER_BACKENDS
': ('django_filters.rest_framework.DjangoFilterBackend',) }

②檢視新增DjangoFilterBackend過濾器

新增filter_backendsfilterset_fields

from django_filters.rest_framework import DjangoFilterBackend

class ArticleListViewset(mixins.ListModelMixin,
                         mixins.CreateModelMixin,
                         viewsets.GenericViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    pagination_class = StandardResultsSetPagination
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['category', 'user']

執行後在介面上出現了過濾器,增加了文章類別文章作者兩個過濾欄位,可以選擇並且聯合過濾。但是有缺點就是無法按照區間進行過濾,比如點選量

③使用filterset方法自定義過濾

在blogs目錄下新建filters.py檔案,用來寫過濾

from django_filters import rest_framework as filters
from .models import Article

class ArticleFilter(filters.FilterSet):
    """
    文章的過濾類
    """
    click_min = filters.NumberFilter(field_name="click_num", lookup_expr='gte')
    click_max = filters.NumberFilter(field_name="click_num", lookup_expr='lte')
    favor_min = filters.NumberFilter(field_name='favor_num', help_text="最低收藏量", lookup_expr='gte')
    comment_min = filters.NumberFilter(field_name='comment_num', help_text="最低評論量", lookup_expr='gte')
    title = filters.CharFilter(field_name='title', help_text='按標題模糊查詢', lookup_expr='icontains')

    class Meta:
        model = Article
        fields = ['category', 'tags', 'user', 'title', 'click_min', 'click_max', 'favor_min', 'comment_min']

編輯blogs目錄下的views.py,去掉filterset_fields,新增filterset_class

from blogs.filters import ArticleFilter

class ArticleListViewset(mixins.ListModelMixin,
                         mixins.CreateModelMixin,
                         viewsets.GenericViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    pagination_class = StandardResultsSetPagination
    filterset_class = ArticleFilter

執行開啟過濾器後可以看到過濾條件都有了

搜尋功能實現

使用SearchFilter方法,filter_backends新增SearchFilter,新增search_fields

from rest_framework.filters import SearchFilter

class ArticleListViewset(mixins.ListModelMixin,
                         mixins.CreateModelMixin,
                         viewsets.GenericViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    pagination_class = StandardResultsSetPagination
    filter_backends = [DjangoFilterBackend, SearchFilter]
    filterset_class = ArticleFilter
    search_fields = ['title', 'brief', 'content']

搜尋框輸入父親,請求路徑變成了http://localhost:8000/api/v1/articles/?search=父親

排序功能實現

使用OrderingFilter方法,filter_backends新增OrderingFilter,新增ordering_fields

from rest_framework.filters import SearchFilter, OrderingFilter

class ArticleListViewset(mixins.ListModelMixin,
                         mixins.CreateModelMixin,
                         viewsets.GenericViewSet):
     """文章列表頁,分頁,搜尋,過濾,排序"""
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer
    pagination_class = StandardResultsSetPagination
    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    filterset_class = ArticleFilter
    search_fields = ['title', 'brief', 'content']
    ordering_fields = ['click_num', 'favor_num', 'comment_num', 'add_time']

執行後過濾器可以看到過濾器欄位、搜尋、排序功能

轉:http://www.zhangyanc.club/article/fiter-search/

DRF過濾器文件:http://www.iamnancy.top/djangorestframework/Filtering/

django-filters官方文件:https://django-filter.readthedocs.io/en/master/guide/rest_framework.html