I have a list of names that I want to match case insensitive, is there a way to do it without using a loop like below?
我有一个要匹配不区分大小写的名称列表,有什么方法可以不使用下面这样的循环吗?
a = ['name1', 'name2', 'name3']
result = any([Name.objects.filter(name__iexact=name) for name in a])
6 个解决方案
#1
27
Unfortunatley, there are no __iin
field lookup. But there is a iregex
that might be useful, like so:
不幸的是,这里没有查找。但是有一个iregex可能是有用的,比如:
result = Name.objects.filter(name__iregex=r'(name1|name2|name3)')
or even:
甚至:
a = ['name1', 'name2', 'name3']
result = Name.objects.filter(name__iregex=r'(' + '|'.join(a) + ')')
Note that if a can contain characters that are special in a regex, you need to escape them properly.
请注意,如果a可以包含regex中特殊的字符,那么您需要正确地避开它们。
NEWS: In Djano 1.7 it is possible to create your own lookups, so you can actually use filter(name__iin=['name1', 'name2', 'name3'])
after proper initialization. See https://docs.djangoproject.com/en/1.7/ref/models/lookups/ for details.
新闻:在Djano 1.7中,可以创建自己的查找,因此您可以在正确的初始化之后实际使用filter(name__iin=['name1', 'name2', 'name3'])。有关详细信息,请参阅https://docs.djangoproject.com/en/1.7/ref/models/lookups/。
#2
15
In Postgresql you could try creating a case insensitive index as described here:
在Postgresql中,您可以尝试创建一个不区分大小写的索引,如下所示:
https://*.com/a/4124225/110274
https://*.com/a/4124225/110274
Then run a query:
然后运行一个查询:
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)
Index search will run faster than the regex matching query.
索引搜索将比regex匹配查询运行得更快。
#3
3
Adding onto what Rasmuj said, escape any user-input like so
再加上Rasmuj所说的,转义任何用户输入
import re
result = Name.objects.filter(name__iregex=r'(' + '|'.join([re.escape(n) for n in a]) + ')')
#4
3
Keep in mind that at least in MySQL you have to set utf8_bin
collation in your tables to actually make them case sensitive. Otherwise they are case preserving but case insensitive. E.g.
请记住,至少在MySQL中,您必须在表中设置utf8_bin排序,以使它们区分大小写。否则它们保存大小写,但不区分大小写。如。
>>> 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>]
So, if portability is not crucial and you use MySQL you may choose to ignore the issue altogether.
因此,如果可移植性不是很重要,而您使用MySQL,您可能会选择完全忽略这个问题。
#5
2
Another way to this using django query functions and annotation
使用django查询函数和注释实现此目的的另一种方法
from django.db.models.functions import Lower
Record.objects.annotate(name_lower=Lower('name')).filter(name_lower__in=['two', 'one']
#6
0
Here is an example of custom User model classmethod
to filter users by email case-insensitive
下面是一个自定义用户模型类方法的示例,该方法通过邮件不区分大小写来过滤用户
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)
#1
27
Unfortunatley, there are no __iin
field lookup. But there is a iregex
that might be useful, like so:
不幸的是,这里没有查找。但是有一个iregex可能是有用的,比如:
result = Name.objects.filter(name__iregex=r'(name1|name2|name3)')
or even:
甚至:
a = ['name1', 'name2', 'name3']
result = Name.objects.filter(name__iregex=r'(' + '|'.join(a) + ')')
Note that if a can contain characters that are special in a regex, you need to escape them properly.
请注意,如果a可以包含regex中特殊的字符,那么您需要正确地避开它们。
NEWS: In Djano 1.7 it is possible to create your own lookups, so you can actually use filter(name__iin=['name1', 'name2', 'name3'])
after proper initialization. See https://docs.djangoproject.com/en/1.7/ref/models/lookups/ for details.
新闻:在Djano 1.7中,可以创建自己的查找,因此您可以在正确的初始化之后实际使用filter(name__iin=['name1', 'name2', 'name3'])。有关详细信息,请参阅https://docs.djangoproject.com/en/1.7/ref/models/lookups/。
#2
15
In Postgresql you could try creating a case insensitive index as described here:
在Postgresql中,您可以尝试创建一个不区分大小写的索引,如下所示:
https://*.com/a/4124225/110274
https://*.com/a/4124225/110274
Then run a query:
然后运行一个查询:
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)
Index search will run faster than the regex matching query.
索引搜索将比regex匹配查询运行得更快。
#3
3
Adding onto what Rasmuj said, escape any user-input like so
再加上Rasmuj所说的,转义任何用户输入
import re
result = Name.objects.filter(name__iregex=r'(' + '|'.join([re.escape(n) for n in a]) + ')')
#4
3
Keep in mind that at least in MySQL you have to set utf8_bin
collation in your tables to actually make them case sensitive. Otherwise they are case preserving but case insensitive. E.g.
请记住,至少在MySQL中,您必须在表中设置utf8_bin排序,以使它们区分大小写。否则它们保存大小写,但不区分大小写。如。
>>> 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>]
So, if portability is not crucial and you use MySQL you may choose to ignore the issue altogether.
因此,如果可移植性不是很重要,而您使用MySQL,您可能会选择完全忽略这个问题。
#5
2
Another way to this using django query functions and annotation
使用django查询函数和注释实现此目的的另一种方法
from django.db.models.functions import Lower
Record.objects.annotate(name_lower=Lower('name')).filter(name_lower__in=['two', 'one']
#6
0
Here is an example of custom User model classmethod
to filter users by email case-insensitive
下面是一个自定义用户模型类方法的示例,该方法通过邮件不区分大小写来过滤用户
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)