【问题标题】:Using django-filters, how can you do a lookup on multiple fields using OR?使用 django-filters,如何使用 OR 查找多个字段?
【发布时间】:2018-07-15 16:01:48
【问题描述】:

假设我想过滤一个内置的 django User 模型,但我只想在 1 个过滤器字段中这样做,而不是每个字段一个过滤器。也就是说,我想直接在过滤器字段中模拟 django 管理员的 search_fields (django admin search_fields docs) 的行为。

因此,例如,我不想为field_name='first_name' 设置一个过滤器,然后为field_name'last_name' 设置另一个过滤器等等,我想做类似field_name=['first_name', 'last_name', 'email', 'username'] 的事情,其中​​可以使用相同的lookup_expr='icontains'。然后查询是一个简单的 OR 查找。这是内置的吗?我在django-filter docs 中找不到。

或者我必须为此制作自定义过滤器。这似乎是一个非常常见的用例。

【问题讨论】:

  • @Frost 这是关于一个特定的包django-filter 以及如何使用这个包正确实现它。这不是关于如何进行通用的or 查询...
  • 哦,对不起。我错过了那部分。我的错。

标签: django django-filter


【解决方案1】:

我通过使用 Q 对象的自定义过滤器做到了这一点。

import django_filters
from django.db.models import Q

class UserFilter(django_filters.FilterSet):
    multi_name_fields = django_filters.CharFilter(method='filter_by_all_name_fields')

    class Meta:
        model = User
        fields = []

    def filter_by_all_name_fields(self, queryset, name, value):
        return queryset.filter(
            Q(first_name__icontains=value) | Q(last_name__icontains=value) | Q(username__icontains=value) | Q(email__icontains=value)
        )

然后确保根据新的过滤器字段(multi_name_fields)进行过滤,这应该会返回您要查找的内容。

【讨论】:

    【解决方案2】:

    我做过类似的事情。这应该会有所帮助:

    def filter_by_all_name_fields(self, queryset, name, value):
    """
    Split the filter value into separate search terms and construct a set of queries from this. The set of queries
    includes an icontains lookup for the lookup fields for each of the search terms. The set of queries is then joined
    with the OR operator.
    """
    lookups = ['first_name__icontains', 'last_name__icontains', 'username__icontains', 'email__icontains',]
    
    or_queries = [Q(**{lookup: value}) for lookup in lookups]
    
    return queryset.filter(reduce(operator.or_, or_queries))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-13
      • 1970-01-01
      • 1970-01-01
      • 2021-09-05
      • 2021-08-11
      • 2011-02-07
      • 1970-01-01
      相关资源
      最近更新 更多