我有一个我希望匹配不区分大小写的名称列表,有没有办法在不使用下面的循环的情况下执行此操作?
a = ['name1', 'name2', 'name3']
result = any([Name.objects.filter(name__iexact=name) for name in a])
答案 0 :(得分:34)
不幸的是,没有 __iin
字段查找。但是有一个iregex
可能有用,就像这样:
result = Name.objects.filter(name__iregex=r'(name1|name2|name3)')
甚至:
a = ['name1', 'name2', 'name3']
result = Name.objects.filter(name__iregex=r'(' + '|'.join(a) + ')')
请注意,如果a可以包含正则表达式中特殊的字符,则需要正确escape。
新闻:在Djano 1.7中,可以创建自己的查找,因此您可以在正确初始化后实际使用filter(name__iin=['name1', 'name2', 'name3'])
。有关详细信息,请参阅https://docs.djangoproject.com/en/1.7/ref/models/lookups/。
答案 1 :(得分:19)
在Postgresql中,您可以尝试创建不区分大小写的索引,如下所述:
https://stackoverflow.com/a/4124225/110274
然后运行查询:
from django.db.models import Q
name_filter = Q()
for name in names:
name_filter |= Q(name__iexact=name)
result = Name.objects.filter(name_filter)
索引搜索的运行速度将快于正则表达式匹配查询。
答案 2 :(得分:11)
from django.db.models.functions import Lower
Record.objects.annotate(name_lower=Lower('name')).filter(name_lower__in=['two', 'one']
答案 3 :(得分:4)
请记住,至少在MySQL中,您必须在表中设置utf8_bin
排序规则才能使它们区分大小写。否则它们保留大小写但不区分大小写。 E.g。
>>> models.Person.objects.filter(first__in=['John', 'Ringo'])
[<Person: John Lennon>, <Person: Ringo Starr>]
>>> models.Person.objects.filter(first__in=['joHn', 'RiNgO'])
[<Person: John Lennon>, <Person: Ringo Starr>]
因此,如果可移植性并不重要且您使用MySQL,则可以选择完全忽略该问题。
答案 4 :(得分:3)
添加Rasmuj所说的,逃避任何用户输入,如此
import re
result = Name.objects.filter(name__iregex=r'(' + '|'.join([re.escape(n) for n in a]) + ')')
答案 5 :(得分:1)
我正在将Exgeny的想法扩展为两个方面。
function writeToDb (agent) {
// Get parameter from Dialogflow with the string to add to the database
const databaseEntry = agent.parameters.databaseEntry;
// Get the database collection 'dialogflow' and document 'agent' and store
// the document {entry: "<value of database entry>"} in the 'agent' document
const dialogflowAgentRef = db.collection('dialogflow').doc('agent');
return db.runTransaction(t => {
t.set(dialogflowAgentRef, {entry: databaseEntry});
return Promise.resolve('Write complete');
}).then(doc => {
agent.add(`Wrote "${databaseEntry}" to the Firestore database.`);
}).catch(err => {
console.log(`Error writing to Firestore: ${err}`);
agent.add(`Failed to write "${databaseEntry}" to the Firestore database.`);
});
}
答案 6 :(得分:0)
以下是自定义用户模型classmethod
的示例,用于通过不区分大小写的电子邮件过滤用户
from django.db.models import Q
@classmethod
def get_users_by_email_query(cls, emails):
q = Q()
for email in [email.strip() for email in emails]:
q = q | Q(email__iexact=email)
return cls.objects.filter(q)