05.django 搜索与过滤

django-filter

https://github.com/carltongibson/django-filterhttps://django-filter.readthedocs.io/en/master/guide/rest_framework.htmlhttps://django-filter.readthedocs.io/en/master/ref/filters.html

https://github.com/carltongibson/django-filter

pip install django-filter

INSTALLED_APPS = [
    ...
    'django_filters',
]


    'DEFAULT_FILTER_BACKENDS': (
        'django_filters.rest_framework.DjangoFilterBackend',    # 过滤功能
        'rest_framework.filters.SearchFilter',                  # 搜索功能
        'rest_framework.filters.OrderingFilter',                # 排序功能
    ),
全局设置默认搜索,在需要搜索的地方加上对应的字段元组即可filter_fields = ('字段1','字段2')
queryset = Idc.objects.all()
    serializer_class = IdcSerializer
    # filter_backends = (DjangoFilterBackend,)
    filter_fields = ('name','letter')

image

一. 视图函数指定搜索 - 最简精确搜索配置方法
from django_filters import rest_framework as filters

class ProductFilter(filters.FilterSet):
    ...
    
from django_filters import rest_framework as filters

class ProductList(generics.ListAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filterset_fields = ('category', 'in_stock')
二. 自定义搜索 - 精确搜索配置方法
  • 1.定义一个 filter.py 文件
from django_filters import rest_framework as filters
from idcs.models import Idc
from django.db.models import Q


class IdcFilter(filters.FilterSet):
    class Meta:
        model = Idc
        fields = ['name','letter']
  • 2.在视图函数应用
queryset = Idc.objects.all()
    serializer_class = IdcSerializer
    # filter_backends = (DjangoFilterBackend,)
    # filter_fields = ('name','letter')
    filter_class = IdcFilter

image

三. 自定义搜索 - 单字段模糊搜索
from django_filters import rest_framework as filters
from idcs.models import Idc
from django.db.models import Q


class IdcFilter(filters.FilterSet):
    name = filters.CharFilter(field_name="name", lookup_expr='icontains')

    class Meta:
        model = Idc
        fields = ['name','letter']

image

四. 自定义搜索 - 多个字段模糊搜索 方法搜索

变量是前端传过来搜索的 key

from django_filters import rest_framework as filters
from idcs.models import Idc
from django.db.models import Q


class IdcFilter(filters.FilterSet):
    name = filters.CharFilter(field_name="name", lookup_expr='icontains')
    contact = filters.CharFilter(method='by_contact')


    def by_contact(self, queryset, name, value):
        # name  是要搜索的key value是搜索的value
        return queryset.filter(Q(phone__icontains=value)|Q(email__icontains=value))

    class Meta:
        model = Idc
        fields = ['name','letter','contact']

image

总结
  • 1.在 settings 设置全局视图搜索配置
'DEFAULT_FILTER_BACKENDS': (
        'django_filters.rest_framework.DjangoFilterBackend',    # 过滤功能
        'rest_framework.filters.SearchFilter',                  # 搜索功能
        'rest_framework.filters.OrderingFilter',                # 排序功能
    ),
  • 2.每个视图里面指定精确搜索字段
filter_fields = ('name','letter')
  • 3.模糊搜索使用自定义搜索
ORM
operators = {  
        'exact': '= %s',  
        'iexact': 'LIKE %s',  
        'contains': 'LIKE BINARY %s',  
        'icontains': 'LIKE %s',  
        'regex': 'REGEXP BINARY %s',  
        'iregex': 'REGEXP %s',  
        'gt': '> %s',  
        'gte': '>= %s',  
        'lt': '< %s',  
        'lte': '<= %s',  
        'startswith': 'LIKE BINARY %s',  
        'endswith': 'LIKE BINARY %s',  
        'istartswith': 'LIKE %s',  
        'iendswith': 'LIKE %s',  
    }
search 与 ordering
  • serchar 前端传回来的关键字是 search,重写 SEARCH_PARAM 覆盖
  • ordering 前端传回来的关键字是 ordering,重写 ORDERING_PARAM 覆
from rest_framework import filters

    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = GoodsFilter
    search_fields = ('name', 'goods_brief', 'goods_desc')
    ordering_fields = ('sold_num', 'shop_price')
'^' :以xx字符串开始搜索
'=' :完全匹配
'@' :全文搜索(目前只支持Django的MySQL后端)
'$' :正则表达式搜索
原始的搜索方法
from rest_framework import generics
class ArticleViewSet(generics.ListAPIView):
    queryset = Article.objects.all()  # 查询结果集
    serializer_class = ArticleSerializer # 序列化类
    pagination_class = ArticlePagination   # 自定义分页会覆盖settings全局配置的

    def get_queryset(self):
        queryset = Article.objects.all()
        read_num = self.request.query_params.get('read_num', 0)  # 获取查询字段值
        if read_num:
            queryset = queryset.filter(read_num__gt=int(read_num))

        return queryset
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jenvid.yang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值