django-filter 23.3 文档翻译(二)

137 阅读3分钟

FilterSet选项

Meta选项

使用model自动生成filter

对于给定model的字段,FilterSet有能力自动生成对应的filters. 类似于Django的ModelForm, filters是基于潜在的模型类字段的类型创建的。model选项必须结合fields(选择哪些字段可供筛选)或者exclude(选择哪些字段不能筛选)选项,就像Django的ModelForm类一样。

class UserFilter(FilterSet):
    class Meta:
        model = User
        fields = ['username', 'last_login']

声明可筛选fields

fields选项可以结合model来自动生成filters。注意生成的filters不会重写FilterSet中声明的filters。fields选项可以接受两种语法:

  1. 一个字段名的列表
  2. 一个包括字段名及其可接受的查找方式列表的字典
class UserFilter(FilterSet):
    class Meta:
        model = User
        fields = ['username', 'last_login']
        
# 或者

class UserFilter(FilterSet):
    class Meta:
        model = User
        fields = {
            'username': ['exact', 'contains'],
            'last_login': ['exact', 'year__gt']
        }

列表语法会为每一个fields的字段创造一个exact查找filter。字典语法会为其中的字段的每一个查询表达式创造一个filter。这些表达式可能包括转换和查找,具体参见Lookup API reference

注意不需要把声明的filters包含进fields列表。在fields字典中添加声明性别名会引发错误

class UserFilter(django_filters.FilterSet):
    username = filters.CharFilter()
    login_timestamp = filters.IsoDateTimeFilter(field_name='last_login')

    class Meta:
        model = User
        fields = {
            'username': ['exact', 'contains'],
            'login_timestamp': ['exact'],
        }

TypeError("'Meta.fields' contains fields that are not defined on this FilterSet: login_timestamp")

禁用筛选字段exclude

exclude选项接受一个不允许自动生成filter的字段黑名单。注意那些在FilterSet中生命的filters不会被禁用。

class UserFilter(FilterSet):
    class Meta:
        model = User
        exclude = ['password']

自定义filter生成filter_overrides

内部的Meta元类接受可选的参数filter_overrides参数。这是模型字段到filter类的映射。

class ProductFilter(django_filters.FilterSet):

     class Meta:
         model = Product
         fields = ['name', 'release_date']
         filter_overrides = {
             models.CharField: {
                 'filter_class': django_filters.CharFilter,
                 'extra': lambda f: {
                     'lookup_expr': 'icontains',
                 },
             },
             models.BooleanField: {
                 'filter_class': django_filters.BooleanFilter,
                 'extra': lambda f: {
                     'widget': forms.CheckboxInput,
                 },
             },
         }

覆盖FIlterSet方法

当覆盖类方法时,引用super(MyFilterSet, cls)可能会引起NameError异常。这是因为FulterSetMetaclassFilterSet被完全创建之前引用了这些类方法。如果使用python 3.6或者更高的版本,使用无参数的super()语法。

Filter 参考

核心参数

下面是用于所有filters的核心参数。注意这些参数需要结合来创建完整的查询表达式。

field_name

筛选依据的模型字段的名称。如果未提供此参数,则默认为FilterSet类上filter的属性名称。字段名可以通过将关联部分与ORM查找分隔符(__)连接来建立关系。例如产品的manufacturer__name

lookup_expr

调用filter时执行的字段查找。默认为exact, 如果表达式部分由ORM查找分隔符(__)连接,lookup_expr可以包含转换(transforms)。例如,通过年部分来筛选日期(datetime),year__gt

仅关键字参数

下面的可选参数可以被用来修改全部filters的行为

method

一个可选的参数,告诉filter如何处理queryset。

class BookFilter(FilterSet):
    # 通过书籍是否出版来筛选
    pubilshed = BooleanFilter(filter_name='published_on', method='filter_published')
    
    def filter_published(self, queryset, name, value):
        # 构建完整的查询表达式
        lookup = '__'.join[name, 'isnull']   # lookup = f"{name}__isnull"
        return queryset.filter(**{look: False})
        
    class Meta:
        model = Book
        fields = ['pubilshed']

以下代码功能相同

def filter_not_empty(queryset, name, value):
    lookup = '__'.join([name, 'isnull'])
    return queryset.filter(**{lookup: Flase})
    
class BookFilter(FilterSet):
    # 通过书籍是否出版来筛选
    pubilshed = BooleanFilter(filter_name='published_on', method=filter_not_empty)
    
    class Meta:
        model = Book
        fields = ['published']

Filter

OrderingFilter

让queryset排序。它接受两个用于构建排序选项的附加参数。

  • fields是{模型字段名: 参数名称}的映射。