django-filter 作用
提供了一种简单的方法来根据用户提供的参数过滤查询集。
安装
$ pip install django-filter
INSTALLED_APPS = [
...
'django_filters',
]
自定义过滤字段
from django_filters.rest_framework import filters
from django_filters.rest_framework import FilterSet
label = filters.CharFilter(
method="label_filter", // 这里注意:使用关键字 method 指定方法名
label="标签名称"
)
def label_filter(self, queryset, name, value):
"""自定义标签,使支持多标签筛选
name: key
value: 值
如搜索标签是 abc 的:label: "abc"
"""
label = self.request.query_params.get(name)
if label is not None:
labels = value.split(",")
return queryset.filter(label__name__in=labels)
return queryset
支持跨表搜索
label = filters.CharFilter(field_name="label__name", label="标签名称")
重写 list 方法
如果没有额外的需求,直接在 filterset 里面定义好就行,不用重写 list 方法。
class OtherFileViewSet(ModelViewSet):
filter_class = filter.OtherFileFilterSet
def list(self, request, *args, **kwargs):
"""补丁文件列表
QueryString:
name="其他软件名称" // 其他软件名称
label="标签1" // 标签,支持多个
sort=cited_counter, file_size // 被引用次数,正序:cited_counter,倒序:-cited_counter
created_by="admin" // 创建人
updated_by="admin" // 更新人
start_created, end_created="2022-04-20, 2022-04-25" // 创建时间
start_updated, end_updated="2022-04-20, 2022-04-25" // 更新时间
"""
sort = request.query_params.get("sort")
serializer = self.get_serializer(self.get_queryset(), many=True)
sort_field = constants.SORT.get(sort)
if sort_field is not None:
sort_data = sorted(serializer.data, key=lambda x: x["file_size"], reverse=sort_field)
else:
# 这里注意,filter_queryset 是需要将 queryset 传进去,表示只筛选该 queryset 里面指定的字段。
filter_qs = self.filter_queryset(self.get_queryset())
sort_data = self.get_serializer(filter_qs, many=True).data
page = self.paginate_queryset(sort_data)
if page is not None:
return self.get_paginated_response(page)
return Response(sort_data)
支持的匹配方法
一般模型中支持的类型,这里都支持,比如:
gte、lte、contains、icontains、exact、iexact 等
支持排序
from django_filters.rest_framework import filters
from django_filters.rest_framework import FilterSet
class BaseFilterSet(FilterSet):
sort = filters.OrderingFilter(
# 支持多个,也可以指定 ordering_fields
fields=("cited_counter", "-cited_counter"),
label="被引用次数"
)
参考文献
django-filter: https://django-filter.readthedocs.io/en/stable/guide/install.html