Django查询未知数量的多个日期范围

时间:2017-05-19 10:04:30

标签: python django postgresql

我有一个表单,允许用户按多个年龄段选择用户:18-24,25-34,35-44等。目前,如果用户选择多个选择列表中的前两个字段,查询将返回用户18-34。如果用户选择18-24岁,35-44岁,则将包括18-44岁的所有年龄,不应包括25-34岁的用户。

如果不知道在用户选择表单之前需要过滤的范围数,您将如何处理查询中的多个范围过滤器?

如果您知道用户要过滤的年龄段数,我知道您可以使用Q链接范围查询。

这是我目前的查询:

query = User.objects.filter(
            gender__in=genders,
            created__in=dates,
            data_source__in=sources,
            dob__range=[dob_from, dob_to]
        )

提前致谢。

1 个答案:

答案 0 :(得分:3)

正如您在问题中所说,您可以使用Q()个对象并将它们组合在一起。这不是一个问题,你不知道会有多少Q()个对象。生成Q()对象的列表,然后将列表缩减为单个Q()

from operator import or_

# import for Python 3, not required in Python 2
from functools import reduce

ranges = [(18,24), (35, 44)]  # hardcoded as an example, you can dynamically generate this
qs = [Q(dob_range=[dob_from_, dob_to]) for (dob_from_, dob_to) in ranges]
# combine the qs
dob_q = reduce(or_, qs, Q())

query = User.objects.filter(
    dob_q,
    gender__in=genders,
    created__in=dates,
    data_source__in=sources,
)

如果您不熟悉reduceor_,可以通过循环列表获得相同的结果:

qs = [Q(dob_range=[dob_from_, dob_to]) for (dob_from_, dob_to) in ranges]
dob_q = Q()
for q in qs:
    dob_q = dob_q | q