这是我的代码:
q = [
"78",
"95",
"77",
"91",
"92",
"93",
"94",
"75",
"27",
"28",
"45",
"89",
"10",
"51",
"02",
"60",
"27",
]
query = reduce(operator.and_, (Q(code_postal__startswith=item) for item in q))
result = Record14.objects.filter(query)
for r in result :
print(r)
我想查询Record14中所有对象,其中code_postal以q数组中的值开头。
我确定我的数据库中有数据,但是查询为空...
我不明白为什么。
答案 0 :(得分:2)
这里的主要问题是您使用and_
作为reduce运算符,这意味着您指定code_postal
应该以{{1}}和78
开头的条件同时。文本/数字不能同时以95
和78
(以及所有其他值)开头。
您可以通过使用95
减少它来轻松解决此问题:
or_
话虽如此,最好在这里使用regular expression [wiki],例如:
from operator import or_
query = reduce(or_, (Q(code_postal__startswith=item) for item in q))
result = Record14.objects.filter(query)
对于您给定的列表from re import escape as reescape
result = Record14.objects.filter(
code_postal__regex= '^({})'.format('|'.join(map(reescape, q)))
)
,这将导致正则表达式:
q
^(78|95|77|91|92|93|94|75|27|28|45|89|10|51|02|60|27)
是此处的开始锚点,并且管道充当“联合”,因此此正则表达式查找以^
,78
,{{1} }等。
答案 1 :(得分:1)
您也可以(自Django 2.1起)将注释与名为Left的数据库函数结合起来,并使用__in
查找:
from django.db.models.functions import Left
records = Record14.objects.annotate(
code_postal_ini=Left('code_postal', 2) # Take the 2 first characters of code_postal
).filter(
code_postal_ini__in=q # Filter if those 2 first chars are contained in q
)
简单。