djnago-filter用法

django-filter用法

集成drf

不指定字段的过滤参数,那么该字段就默认为exact,精准匹配
自定义filter文件内

from django_filters import rest_framework as rs_filters
from .models import *


class TestFilter(rs_filters.FilterSet):
    title = rs_filters.CharFilter(lookup_expr='icontains') # 不指定field_name默认用变量名去对应字段
    # title_name = rs_filters.CharFilter(lookup_expr='icontains', field_name='title')
    max_price = rs_filters.NumberFilter(field_name='price', lookup_expr='lte')
    min_price = rs_filters.NumberFilter(field_name='price', lookup_expr='gte')

    class Meta:
        model = Book
        fields = ['title', 'price']
	不必写max_price or min_price,只需要把price加进去就可以实现过滤
	支持django的双下划线的跨表 eg:fields = ['publish__addr']
	
	此外,字典可用于为每个字段指定多个查找表达式:
	fields = {
            'price': ['lt', 'gt'],
            'release_date': ['exact', 'year__gt'],
        }
	

在view.py内

from django_filters.rest_framework import DjangoFilterBackend
from .filter import TestFilter

class BookAPIView(ListAPIView):
    queryset = Book.objects
    serializer_class = BookSerializer
    filter_backends = [DjangoFilterBackend] # 必须用加DjangoFilterBackend或其子类
    filterset_class = TestFilter # 把自定义的过滤加上

image

过滤器和查找表达式不匹配(in、range、isnull)

直接将过滤器与其模型字段的类型匹配并不总是合适的,因为某些查找需要不同类型的值。in这是、rangeisnull查找的常见问题。我们来看看下面的产品型号:

class Product(models.Model):
    category = models.ForeignKey(Category, null=True)

鉴于这category是可选的,因此希望启用对未分类产品的搜索是合理的。以下是错误配置的 isnull过滤器:

class ProductFilter(django_filters.FilterSet):
    uncategorized = django_filters.NumberFilter(field_name='category', lookup_expr='isnull')

那么问题是什么?虽然基础列类型category是整数,但isnull查找需要一个布尔值。然而,ANumberFilter只验证数字。过滤器不是“表达式感知”的,不会根据它们的lookup_expr. 您应该使用与查找表达式的数据类型匹配的过滤器,而不是模型字段的数据类型。以下将正确地允许您搜索未分类的产品和一组类别的产品:

class NumberInFilter(django_filters.BaseInFilter, django_filters.NumberFilter):
    pass

class ProductFilter(django_filters.FilterSet):
    categories = NumberInFilter(field_name='category', lookup_expr='in')
    uncategorized = django_filters.BooleanFilter(field_name='category', lookup_expr='isnull')

in有关构建和rangecsv过滤器的更多信息。

参数

禁用过滤器字段exclude

exclude选项接受要从自动过滤器生成中排除的字段名称黑名单。请注意,此选项不会禁用直接在FilterSet.

class UserFilter(django_filters.FilterSet):
    class Meta:
        model = User
        exclude = ['password'] # 把password排除

field_name

过滤的模型字段的名称。如果未提供此参数,则默认过滤器在FilterSet类上的属性名称。字段名称可以通过使用 ORM 查找分隔符 ( __) 连接相关部分来遍历关系。例如,产品的manufacturer__name.

lookup_expr

应在过滤器调用中执行的字段查找.默认为 exact. lookup_expr如果表达式部分由 ORM 查找分隔符 ( ) 连接,则可以包含转换__。例如,按年份部分过滤日期时间year__gt

method

一个可选参数,告诉过滤器如何处理查询集。它可以接受可调用对象或FilterSet. 可调用对象接收一个QuerySet、要过滤的模型字段的名称以及要过滤的值。它应该返回一个经过过滤的Queryset.

请注意,该值由 验证Filter.field,因此应该不需要原始值转换和空值检查。

class F(FilterSet):
    """Filter for Books by if books are published or not"""
    published = BooleanFilter(field_name='published_on', method='filter_published')

    def filter_published(self, queryset, name, value):
        # construct the full lookup expression.
        lookup = '__'.join([name, 'isnull'])
        return queryset.filter(**{lookup: False})

        # alternatively, you could opt to hardcode the lookup. e.g.,
        # return queryset.filter(published_on__isnull=False)

    class Meta:
        model = Book
        fields = ['published']

distinct

一个布尔值,指定过滤器是否将在查询集上使用 distinct。当使用跨越关系的过滤器时,此选项可用于消除重复结果。默认为False.

exclude

一个布尔值,指定过滤器是否应该使用filterexclude 在查询集上。默认为False.

required

一个布尔值,指定是否需要过滤器。默认为False.

ChoiceFilter

此过滤器匹配其choices参数中的值。当choices在 上声明过滤器时,必须显式传递FilterSet。例如,

class User(models.Model):
    username = models.CharField(max_length=255)
    first_name = SubCharField(max_length=100)
    last_name = SubSubCharField(max_length=100)

    status = models.IntegerField(choices=STATUS_CHOICES, default=0)

STATUS_CHOICES = (
    (0, 'Regular'),
    (1, 'Manager'),
    (2, 'Admin'),
)

class F(FilterSet):
    status = ChoiceFilter(choices=STATUS_CHOICES)
    class Meta:
        model = User
        fields = ['status']

ChoiceFilter还有一些参数可以选择不过滤,也可以选择按None值过滤。每个参数都有一个对应的全局设置(设置参考)。

  • empty_label:用于选择不过滤的显示标签。通过将此参数设置为 可以禁用该选择None。默认为 FILTERS_EMPTY_CHOICE_LABEL.
  • null_label:用于选择按None 值过滤的显示标签。通过将此参数设置为 可以禁用该选择None。默认为FILTERS_NULL_CHOICE_LABEL.
  • null_value: 要匹配的特殊值以启用按None 值过滤。此值默认FILTERS_NULL_CHOICE_VALUE为非空值('', None, [], (), {})。
posted @ 2022-08-13 18:51  zong涵  阅读(205)  评论(0编辑  收藏  举报