вот мой код:
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.
У меня есть данные в моей базе данных, я уверен, но запрос пуст...
Я не понимаю, почему.






Основная проблема здесь заключается в том, что вы используете and_ в качестве оператора сокращения, а это означает, что вы указываете в качестве условия, что code_postal должен начинаться с 78 и 95 одновременно. Ни один текст/число не может начинаться с 78 и 95 (и всех других значений) одновременно.
Вы можете легко исправить это, уменьшив это с помощью or_:
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, 95, 77 и т. д.
Вы также можете (начиная с Django 2.1) объединить аннотацию с функцией базы данных с именем Осталось и использовать поиск __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
)
просто.
Вы используете
and_в качестве редуктора, так что это означает, что вы говорите: что почтовый индекс должен начинаться с 78 и должен начинаться с 10. Текст не может начинаться с обоих одновременно.