Django查询:数组中带有startswith的请求

时间:2019-05-15 19:35:37

标签: python django django-queryset

这是我的代码:

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数组中的值开头。

我确定我的数据库中有数据,但是查询为空...

我不明白为什么。

2 个答案:

答案 0 :(得分:2)

这里的主要问题是您使用and_作为reduce运算符,这意味着您指定code_postal应该以{{1​​}}和78开头的条件同时。文本/数字不能同时以9578(以及所有其他值)开头。

您可以通过使用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
)

简单。