zoukankan      html  css  js  c++  java
  • 05.django 搜索与过滤

    django-filter

    https://github.com/carltongibson/django-filter
    https://django-filter.readthedocs.io/en/master/guide/rest_framework.html
    https://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
    
  • 相关阅读:
    使用QTM 博客客户端
    sdut 2080 最长公共子序列问题
    sdut 1730 数字三角形问题
    HDOJ 1905 Pseudoprime numbers(模运算)
    HDU 1285确定比赛名次(拓补排序)
    HDU 2094产生冠军(map)
    HDOJ 1228 A+B(map水题)
    HDOJ 1713 相遇周期 (最大公约数与最小公倍数)
    HDOJ 2098 分拆素数和(筛选法求素数)
    (转)最大子序列和问题
  • 原文地址:https://www.cnblogs.com/jenvid/p/12927264.html
Copyright © 2011-2022 走看看