我有一个表单,允许用户按多个年龄段选择用户: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]
)
提前致谢。
答案 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,
)
如果您不熟悉reduce
和or_
,可以通过循环列表获得相同的结果:
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