字段過濾
一般過濾可以重寫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')