DRF搜索、分页、排序、过滤的实现

一、搜索

搜索

REST framework有提供了一个比较简洁的搜索功能给我们使用。

class GoodsListViewSet(viewsets.ModelViewSet):
    #数据
    queryset = Goods.objects.all()
    # 指定序列化的类
    serializer_class = GoodsSerializer
    #配置搜索功能
    filter_backends = (filters.SearchFilter,)
    #设置搜索的关键字
    search_fields=('name','goods_brief','goods_desc')

'''
        ^ :搜索关键字开头的数据
        = :完全匹配搜索                  =name :则是完全匹配,不能模糊搜索
        @ :全文搜索(目前只支持MySQL)
        $ :正则表达式搜索
'''

 

 在没有配置filter_backends之前,显示的效果如下:

 配置filter_backends之后:会出现一个过滤器

 

二、过滤

1、自定义过滤

class GoodsListViewSet(viewsets.ModelViewSet):
    serializer_class=GoodsSerializer
    #自定义过滤
    def get_query(self):
        price_min=self.request.query_params.get('price_min',0)
        if price_min:
            queryset=queryset.filter(shop_price__gt=int(price_min))
        return queryset

 2、使用django-filter搜索

首先安装django-filter:pip install django-filter  , 然后注册到app

自定义过滤类:

class GoodsFilter(django_filters.rest_framework.FilterSet):
    """
    商品的过滤类
    """
    pricemin = django_filters.NumberFilter(field_name='shop_price', help_text="最低价格", lookup_expr='gte')
    pricemax = django_filters.NumberFilter(field_name='shop_price', lookup_expr='lte')
    top_category = django_filters.NumberFilter(method='top_category_filter')

    def top_category_filter(self, queryset, name, value):
        return queryset.filter(Q(category_id=value) | Q(category__parent_category_id=value) | Q(
            category__parent_category__parent_category_id=value))

    class Meta:
        model = Goods
        fields = ['pricemin', 'pricemax', 'is_hot', 'is_new']

 views.py:

class GoodsListViewSet(viewsets.ModelViewSet):
    # 数据
    queryset = Goods.objects.all()
    # 指定序列化的类
    serializer_class = GoodsSerializer
    # 配置搜索功能
    filter_backends = (DjangoFilterBackend, filters.SearchFilter)
    # 设置搜索的关键字
    # filter_fields = ('name',)  # 默认是全匹配,可自定义
    filter_class = GoodsFilter  # 自定义过滤
    search_fields = ('name', 'goods_brief', 'goods_desc')  # 搜索
 

效果如下:

三、分页

1、全局分页

在settings.py文件中设置:

    REST_FRAMEWORK = {
        'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination'
    }

 常见参数:

  1. PageNumberPagination类包括可以覆盖以修改分页样式的许多属性,要设置这些属性,应覆盖PageNumberPagination类,然后如上所示启用自定义分页类。
  2. django_paginator_class:使用的Django Paginator类,默认是django.core.paginator.Paginator,对大部分用例是适用的。
  3. page_size:数值,页面大小,默认是全局PAGE_SIZE的值。
  4. page_query_param:字符串,查询参数的名称,默认是'page'
  5. page_size_query_param:字符串,请求设置页面大小的参数名称,默认是None,表示客户端可能无法控制请求的页面大小。
  6. max_page_size:字符串,最大允许请求的页面大小, 此属性仅在page_size_query_param也被设置时有效。
  7. last_page_strings:字符串列表或者元组,默认是('last',)
  8. template:分页控件使用的模板的名称,可以覆盖或设置为None,默认为"rest_framework/pagination/numbers.html"

 2、自定义分页

# 定制分页
class GoodsPagination(PageNumberPagination):
    page_size = 12  # 每页显示多少个
    page_size_query_param = 'page_size'
    page_query_param = 'page'  # 查询参数的名称。默认是’page‘
    max_page_size = 100

views.py:

class GoodsListViewSet(viewsets.ModelViewSet):
    # 数据
    queryset = Goods.objects.all()
    # 指定序列化的类
    serializer_class = GoodsSerializer
    # 配置搜索功能
    filter_backends = (DjangoFilterBackend, filters.SearchFilter)
    # 设置搜索的关键字
    # filter_fields = ('name',)  # 默认是全匹配,可自定义
    filter_class = GoodsFilter  # 自定义过滤
    search_fields = ('name', 'goods_brief', 'goods_desc')
    pagination_class = GoodsPagination  # 自定义分页设置

 四、排序

在views.pywe的filter_backends添加 filters.OrderingFilter

class GoodsListViewSet(viewsets.ModelViewSet):
    # 数据
    queryset = Goods.objects.all()
    # 指定序列化的类
    serializer_class = GoodsSerializer
    # 配置搜索功能
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    # 设置搜索的关键字
    # filter_fields = ('name',)  # 默认是全匹配,可自定义
    filter_class = GoodsFilter  # 自定义过滤
    search_fields = ('name', 'goods_brief', 'goods_desc')
    pagination_class = GoodsPagination  # 自定义分页设置
    #添加排序字段
    ordering_fields = ('sold_num', 'shop_price')

 效果如下:
 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DRF实现多层级数据的方法主要有两种: 1. 使用 Serializer 嵌套来实现多层级数据 在 Serializer 中可以使用嵌套的方式来表示多层级数据结构,例如: ```python class SubItemSerializer(serializers.ModelSerializer): class Meta: model = SubItem fields = '__all__' class ItemSerializer(serializers.ModelSerializer): sub_items = SubItemSerializer(many=True) class Meta: model = Item fields = '__all__' ``` 在上面的例子中,SubItemSerializer 表示 SubItem 模型的序列化器,ItemSerializer 表示 Item 模型的序列化器,其中 Item 中包含多个 SubItem。通过将 SubItemSerializer 嵌套在 ItemSerializer 中,就能够实现多层级数据的序列化与反序列化。 2. 使用 DRF 的 ModelViewSet 来实现多层级数据的 API DRF 提供了 ModelViewSet 来快速实现基于模型的 API,其中包含了常用的增删改查操作。在 ModelViewSet 中可以通过重写 queryset 和 serializer_class 来实现多层级数据的 API,例如: ```python class ItemViewSet(viewsets.ModelViewSet): queryset = Item.objects.all() serializer_class = ItemSerializer def get_serializer_class(self): if self.action == 'list': return ItemListSerializer return super().get_serializer_class() ``` 在上面的例子中,ItemViewSet 是一个基于 Item 模型的 API,其中 queryset 表示查询的数据集,serializer_class 表示序列化的类。如果需要实现多层级数据的 API,可以在 ItemSerializer 中嵌套 SubItemSerializer,同时根据需要重写 get_serializer_class 方法来选择不同的序列化器。例如,在 list 操作中,可以选择 ItemListSerializer 来表示列表中的数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值