django-filter是drf的第三方包,用来实现条件过滤,和modelviewset配合使用就是如虎添翼,用最少的代码实现功能。下面是django-filter的高级搜索, 比如模糊查询,范围查询等。
class User(models.Model):
username = models.CharField(max_length=100)
email = models.CharField(max_length=100)
created_at = models.DatetimeField()
class UserSerializer(serializers.ModelSerializer):
class Meta:
fields = '__all__'
class UserFilter(django_filters.FilterSet):
sort = django_filters.OrderingFilter(fields=("id",))
class Meta:
model = User
fields = ['username',]
class UserView(ModelViewSet):
queryset = User.objects
serializer_class = UserSerializer
filter_class = UserFilter
想要实现按 username 的模糊查询。上面 ProductFilter 里面的 fields,如果是 list,默认就是按=来匹配。它还支持 dict 的格式,可以选择更多的匹配方式。按 name 的模糊匹配,只需把 fields 改成如下即可:
fields = {
'username': ['icontains'],
"email": ['icontains'],
}
使用 API 查询是原来的 url 是/products/, 模糊查询的 url 就变成/products/?username__icontains=xxx。注意必须加__icontains,否则就是查询所有。
接下来实现按 created_at 按日期范围来搜索。一个方法是直接在 fields 里面配置:
fields = {
'username': ['icontains'],
'created_at': ['date__gte', 'date__lte']
}
然后就可以用下面的 url 来进行日期范围搜索:/products/?created_at__date__gte=2019-01-01&created_at__date__lte=2020-01-01
如果你觉得这个 param 名字太长,还可以自定义 filter 字段:
class UserFilter(django_filters.FilterSet):
sort = django_filters.OrderingFilter(fields=('created_at',))
min_date = django_filters.DateFilter(field_name='created_at__date', lookup_expr='gte')
max_date = django_filters.DateFilter(field_name='created_at__date', lookup_expr='lte')
class Meta:
model = User
fields = {
'username': ['icontains'],
}
然后搜索的 url 变成这样:/products/?min_date=2019-01-01&max_date=2020-01-01