DRF的Filter:字段過濾,查找,排序


字段過濾

一般過濾可以重寫get_queryset方法實現,這時候就可以去掉queryset這個屬性了:

class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination

    # 覆寫GenericAPIView下的該方法,以實現自己對query_set的返回加一些邏輯
    def get_queryset(self):
        # 獲取url參數中傳過來的"要查詢的商品的價格閾值",如果沒有傳就設置為0
        price_min = self.request.query_params.get("price_min", 0)
        return Goods.objects.filter(shop_price__gt=price_min).order_by("shop_price")

現在就可以通過在url里指定參數price_min來實現對獲取到的商品價格的過濾了。

注意在使用這種方法時,要在router.register里配置base_name,不然運行不了。

 

還可以使用django-filter,這個要把它注冊為app,然后就能用了(因為這時候不需要重寫get_queryset方法了,所以就需要把queryset這個屬性拿回來)。然后可以自定義一個filters.py用來寫自定義過濾規則的過濾器:

from django_filters import rest_framework as filters

from .models import Goods


class GoodsFilter(filters.FilterSet):
    """商品的過濾類"""
    # 區間查詢,指定區間的最大最小值
    min_price = filters.NumberFilter(field_name="shop_price", lookup_expr='gte')
    max_price = filters.NumberFilter(field_name="shop_price", lookup_expr='lte')
    # 模糊查詢,這里帶i是忽略大小寫
    name = filters.CharFilter(field_name="name", lookup_expr="icontains")

    class Meta:
        model = Goods
        fields = ['min_price', 'max_price', 'name']

然后在views.py的相關視圖類里指定filter_class為這個自定義的過濾器類:

from .filters import GoodsFilter

class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination
    filter_backends = (DjangoFilterBackend,)
    queryset = Goods.objects.all()
    # filter_fields = ('name', 'shop_price')
    filter_class = GoodsFilter

在這個例子里配置完了之后,效果就是可以在url里指定min_price和max_price的值,來控制所返回的JSON中上shop_price值所在的區間,實現區間過濾;使用name實現模糊查詢。

查找

要實現查找,只要在視圖層配置filters.SearchFilter和search_fields=要查找的字段元組即可:

from rest_framework import filters

class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination
    filter_backends = (DjangoFilterBackend, filters.SearchFilter)
    queryset = Goods.objects.all()
    # filter_fields = ('name', 'shop_price')
    filter_class = GoodsFilter
    search_fields = ('name', 'goods_brief', 'goods_desc')

一些符號可以實現復雜的查找方式,比如以。。開頭,全文搜索之類的。

排序

要實現排序,只要在視圖層配置filters.OrderingFilter和ordering_fields=要排序的字段即可:

class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    queryset = Goods.objects.all()
    # filter_fields = ('name', 'shop_price')
    filter_class = GoodsFilter
    search_fields = ('name', 'goods_brief', 'goods_desc')
    ordering_fields = ('sold_num', 'add_time')

 


免責聲明!

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



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