(生鲜项目)12. drf 的过滤, 搜索, 排序 (使用django_filter插件完成自定义字段过滤)
第一种方式: 重写get_queryset()方法
goods.views.py
class GoodsListViewSet(mixins.ListModelMixin,viewsets.GenericViewSet): """ 商品列表页 """ queryset = Goods.objects.all() serializer_class = GoodsSerializer pagination_class = GoodsPagination def get_queryset(self): queryset = Goods.objects.all() min_price = self.request.query_params.get("min_price",0) if min_price: queryset = queryset.filter(shop_price__gt=int(min_price)) return queryset
在浏览器中去验证, 下图说明已经生效了
第二种方式:使用django-filter
1.安装django_filters, 之前已经装过了, 这里就不重复安装了, 首先进行filter的配置
settings.py
INSTALLED_APPS = [ ... 'django_filters', ... ] REST_FRAMEWORK = { # filter设置 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'], }
goods.views.py
from django_filters.rest_framework import DjangoFilterBackend # 方法六: 使用 filter 完成过滤 class GoodsListViewSet(mixins.ListModelMixin,viewsets.GenericViewSet): """ 商品列表页 """ queryset = Goods.objects.all() serializer_class = GoodsSerializer pagination_class = GoodsPagination filter_backends = [DjangoFilterBackend] # 指定使用字段过滤 filterset_fields = ['name', 'shop_price'] # 指定哪些字段过滤
2. 去浏览器验证, 可以发现多了一个过滤器功能
第三种方式:使用django-filter + 自定义过滤类
1. 我们可以明显感觉到第二种方式的一些缺点, 比如我想查价格大于100且小于200的商品, 它是办不到的, 我想对name字段进行模糊搜索, 它也是办不到的,
这里django_filters插件给我们提供了自定义过滤类的方法, 让我们可以实现功能更为复杂的过滤
2. 新建filters.py
import django_filters from .models import Goods class GoodsFilter(django_filters.rest_framework.FilterSet): """ 商品的过滤类 """ # 自定义过滤条件, 价格最小值, 价格最大值, name的模糊查询, name的全字段匹配 price_min = django_filters.NumberFilter(field_name="shop_price", lookup_expr='gte') price_max = django_filters.NumberFilter(field_name="shop_price", lookup_expr='lte') name = django_filters.CharFilter(field_name="name", lookup_expr='icontains') name_equal = django_filters.CharFilter(field_name="name", ) class Meta: model = Goods fields = ['price_min', 'price_max', 'name', 'name_equal']
3. goos.views.py
from .filters import GoodsFilter # 方法七: 使用 filter + 自定义过滤类 完成过滤 class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): """ 商品列表页 """ queryset = Goods.objects.all() serializer_class = GoodsSerializer pagination_class = GoodsPagination filter_backends = [DjangoFilterBackend] # 指定使用字段过滤 filter_class = GoodsFilter # 指定自定义的过滤器名称
4. 去浏览器测试, 没有问题, 注意这里的name字段仍然是全字段匹配
第四种方式:使用REST自带的filters完成搜索和排序
1. 最后使用REST自带的filters完成搜索和排序
godds.views.py
# 方法七: # 使用 filter插件 + 自定义过滤类 完成过滤 # 使用 django自带的filter实现搜索和排序
from rest_framework import filters
class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): """ 商品列表页, 分页, 字段过滤, 搜索, 排序 """ queryset = Goods.objects.all() serializer_class = GoodsSerializer pagination_class = GoodsPagination filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter] # 指定,字段过滤,搜索,与排序 filter_class = GoodsFilter # 指定自定义的过滤器名称 search_fields = ['name', 'goods_brief', 'goods_desc'] # 指定用于搜索的字段 ordering_fields = ['sold_num', 'add_time'] # 指定用于排序的字段
2. 接下来去浏览器验证, 没有问题
---- over ----