Django-filter 使用指南:构建灵活的数据过滤系统
【免费下载链接】django-filter 项目地址: https://gitcode.com/gh_mirrors/dja/django-filter
概述
Django-filter 是一个强大的 Django 应用,它提供了一种简单而灵活的方式来根据用户提供的参数过滤查询集。本文将详细介绍如何使用 Django-filter 构建数据过滤系统,从基础用法到高级技巧,帮助开发者掌握这一实用工具。
基础用法
模型定义
首先我们需要定义一个模型作为过滤的基础。假设我们有一个产品模型:
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=255)
price = models.DecimalField(max_digits=5, decimal_places=2)
description = models.TextField()
release_date = models.DateField()
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
创建过滤器集
Django-filter 的核心是 FilterSet 类,它类似于 Django 的 ModelForm:
import django_filters
class ProductFilter(django_filters.FilterSet):
name = django_filters.CharFilter(lookup_expr='iexact')
class Meta:
model = Product
fields = ['price', 'release_date']
这个简单的过滤器集允许用户根据产品名称(不区分大小写精确匹配)、价格和发布日期进行过滤。
高级过滤配置
声明式过滤语法
声明式语法提供了最大的灵活性,允许精确控制每个过滤器的行为:
class ProductFilter(django_filters.FilterSet):
price = django_filters.NumberFilter()
price__gt = django_filters.NumberFilter(field_name='price', lookup_expr='gt')
price__lt = django_filters.NumberFilter(field_name='price', lookup_expr='lt')
release_year = django_filters.NumberFilter(
field_name='release_date',
lookup_expr='year'
)
manufacturer__name = django_filters.CharFilter(lookup_expr='icontains')
关键参数说明:
field_name: 指定模型字段名,支持使用__语法跨关系查询lookup_expr: 指定查询表达式,支持 Django 的所有查询表达式
使用 Meta.fields 简化配置
对于简单的过滤需求,可以使用 Meta.fields 快速生成过滤器:
class ProductFilter(django_filters.FilterSet):
class Meta:
model = Product
fields = {
'price': ['lt', 'gt'],
'release_date': ['exact', 'year__gt'],
}
这种写法会自动生成 price__lt、price__gt、release_date 和 release_date__year__gt 等过滤器。
覆盖默认过滤器
可以通过 filter_overrides 覆盖特定字段类型的默认过滤器:
class ProductFilter(django_filters.FilterSet):
class Meta:
model = Product
fields = ['name']
filter_overrides = {
models.CharField: {
'filter_class': django_filters.CharFilter,
'extra': lambda f: {
'lookup_expr': 'icontains',
},
}
}
请求相关的过滤
主查询集过滤
可以通过覆盖 qs 属性实现基于请求的过滤:
class ArticleFilter(django_filters.FilterSet):
@property
def qs(self):
parent = super().qs
user = getattr(self.request, 'user', None)
return parent.filter(is_published=True) | parent.filter(author=user)
模型选择过滤器
对于 ModelChoiceFilter,可以使用可调用对象实现请求相关的过滤:
def departments(request):
if request is None:
return Department.objects.none()
return request.user.company.department_set.all()
class EmployeeFilter(filters.FilterSet):
department = filters.ModelChoiceFilter(queryset=departments)
自定义过滤方法
可以通过 method 参数指定自定义过滤方法:
class UserFilter(django_filters.FilterSet):
username = CharFilter(method='custom_filter')
def custom_filter(self, queryset, name, value):
return queryset.filter(**{name: value})
视图和模板集成
视图实现
在视图中使用过滤器集:
def product_list(request):
f = ProductFilter(request.GET, queryset=Product.objects.all())
return render(request, 'template.html', {'filter': f})
模板示例
在模板中渲染过滤表单和结果:
<form method="get">
{{ filter.form.as_p }}
<input type="submit" />
</form>
{% for obj in filter.qs %}
{{ obj.name }} - ${{ obj.price }}<br />
{% endfor %}
类视图配置
Django-filter 提供了基于类的通用视图:
# urls.py
from django_filters.views import FilterView
urlpatterns = [
path("products/", FilterView.as_view(model=Product), name="product-list"),
]
需要创建 products/product_filter.html 模板来显示结果。
总结
Django-filter 提供了强大而灵活的数据过滤功能,从简单的精确匹配到复杂的跨关系查询,都能轻松实现。通过本文的介绍,开发者应该能够掌握 Django-filter 的核心概念和高级用法,在实际项目中构建出符合需求的数据过滤系统。
【免费下载链接】django-filter 项目地址: https://gitcode.com/gh_mirrors/dja/django-filter
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



