用django-filter实现高级搜索

在上一篇文章中,我们介绍了 django-filter 的基本功能。实际上 django-filter 还可以实现更高级的搜索,比如说文本的模糊查询,日期的范围查询。

继续我们的例子:

class Product(models.Model):
  name = models.CharField(max_length=100)
  created_at = models.DatetimeField()

class ProductSerializer(serializers.ModelSerializer):
  class Meta:
    fields = '__all__'

class ProductFilter(django_filters.FilterSet):
  sort = django_filters.OrderingFilter(fields=('created_at',))

  class Meta:
    model = Product
    fields = ['name',]

class ProductListView(generics.ListView):
  queryset = Product.objects.all()
  serializer_class = ProductSerializer
  filter_backends = (DjangoFilterBackend,)
  filter_class = ProductFilter

首先要实现按 name 的模糊查询。上面 ProductFilter 里面的 fields,如果是 list,默认就是按=来匹配。它还支持 dict 的格式,可以选择更多的匹配方式。按 name 的模糊匹配,只需把 fields 改成如下即可:

fields = {
  'name': ['icontains']
}

使用 API 查询是原来的 url 是/products/, 模糊查询的 url 就变成/products/?name__icontains=xxx

接下来实现按 created_at 按日期范围来搜索。一个方法是直接在 fields 里面配置:

fields = {
  'name': ['icontains'],
  'created_at': ['date__gte', 'date__lte']
}

然后就可以用下面的 url 来进行日期范围搜索:/products/?created_at__date__gte=2018-01-01&created_at__date__lte=2018-04-01

如果你觉得这个 param 名字太长,还可以自定义 filter 字段:

class ProductFilter(django_filters.FilterSet):
  sort = django_filters.OrderingFilter(fields=('created_at',))
  min_date = django_filters.DateFilter(name='created_at__date', lookup_expr='gte')
  max_date = django_filters.DateFilter(name='created_at__date', lookup_expr='lte')

  class Meta:
    model = Product
    fields = {
      'name': ['icontains'],
}

然后搜索的 url 变成这样:/products/?min_date=2018-01-01&max_date=2018-04-01

想一想如果用java写需要多少代码吧...

你可能感兴趣的:(用django-filter实现高级搜索)