使用django-filters,如何使用OR在多个字段上进行查找?

时间:2018-02-05 17:57:49

标签: django django-filter

我想要过滤内置的django User模型,但我只希望在1个过滤器字段中执行此操作,而不是每个字段使用过滤器。也就是说,我想直接在过滤器字段中模拟django管理员search_fieldsdjango admin search_fields docs)的行为。

因此,例如,我没有使用field_name='first_name'的过滤器,而是field_name'last_name'的另一个过滤器,等等,我想做field_name=['first_name', 'last_name', 'email', 'username']之类的事情,其中​​lookup_expr='icontains'相同from pyspark.sql.types import StringType from pyspark.sql.functions import udf from pyspark import SparkContext from pyspark import SparkConf import pyspark.sql.functions as pf import logging import sys from pyspark.sql import SQLContext log = logging.getLogger('EXT') class Test: def __init__(self): pass def ext_udf(self, f): return udf(lambda f: self.test(1)) def test(self,arg): return(arg) def create_df(self): log.info("Test") log.debug("Test") conf = SparkConf().setAppName('Extr') sc = SparkContext(conf=conf) sqlContext = SQLContext(sc) df = SQLContext.createDataFrame(sqlContext,[{'name': 'Alice', 'age': 1}]) df.withColumn('meta-data', self.ext_udf(1)(pf.col("name"))).show() if __name__ == "__main__": logging.basicConfig(stream=sys.stdout, level=logging.INFO) t=Test() t.create_df() 1}}可以使用。然后查询是一个简单的OR查找。这是内置的吗?我无法在django-filter docs中找到它。

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

2 个答案:

答案 0 :(得分: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 )进行过滤,这应该返回您要查找的内容。

答案 1 :(得分:0)

我做了类似的事情。这应该有帮助:

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))