有没有办法在Django中执行不区分大小写的查询?
Django中几乎所有类型的查找都有一个不区分大小写的版本,但在中除外 这是一个问题,因为有时我需要在我确定案例不正确的地方进行查找有没有办法在Django中执行不区分大小写的查询?,django,django-queryset,case-sensitive,Django,Django Queryset,Case Sensitive,Django中几乎所有类型的查找都有一个不区分大小写的版本,但在中除外 这是一个问题,因为有时我需要在我确定案例不正确的地方进行查找 Products.objects.filter(code__in=[user_entered_data_as_list]) 我能做些什么来处理这件事吗?是否有人想出了解决此问题的方法?如果不会产生冲突,可能的解决方法是在保存对象时以及在过滤器中将字符串转换为大写或小写 我通过使MySQL数据库本身不区分大小写来解决这个问题。我怀疑Django的人员是否有兴趣将其
Products.objects.filter(code__in=[user_entered_data_as_list])
我能做些什么来处理这件事吗?是否有人想出了解决此问题的方法?如果不会产生冲突,可能的解决方法是在保存对象时以及在
过滤器中将字符串转换为大写或小写 我通过使MySQL数据库本身不区分大小写来解决这个问题。我怀疑Django的人员是否有兴趣将其作为一项功能添加,或者提供关于如何提供自己的字段查找的文档(假设在不为每个db后端提供代码的情况下这是可能的)
这里有一种方法可以做到这一点,诚然它很笨重
products = Product.objects.filter(**normal_filters_here)
results = Product.objects.none()
for d in user_entered_data_as_list:
results |= products.filter(code__iexact=d)
更优雅的方式是:
[x for x in Products.objects.all() if x.code.upper() in [y.upper() for y in user_entered_data_as_list]]
这是一个不需要案例准备的DB值的解决方案。
它还在DB引擎端进行过滤,这意味着比遍历对象.all()
性能更好
另一个有效的解决方案是将extra与可移植的原始SQLlower()函数配合使用:
MyModel.objects.extra(
select={'lower_' + fieldname: 'lower(' + fieldname + ')'}
).filter('lover_' + fieldname + '__in'=[x.lower() for x in iterable])
另一种解决方案(尽管很粗糙)是在“in”过滤器的list参数中包含原始字符串的不同大小写。例如:用['a','b','c','a','b','c','c','c','b','c']代替['a','b','c']
下面是一个函数,它从字符串列表中构建这样一个列表:
def build_list_for_case_insensitive_query(the_strings):
results = list()
for the_string in the_strings:
results.append(the_string)
if the_string.upper() not in results:
results.append(the_string.upper())
if the_string.lower() not in results:
results.append(the_string.lower())
return results
如果您的数据库是MySQL,Django将不区分大小写地处理查询。虽然我不确定其他人
编辑1:
model_name.objects.filter(location__city__name__in': ['Tokio','Paris',])
将给出以下结果,其中城市名称为
东京或东京或东京或巴黎或巴黎或巴黎
可以使用创建一个查找,以便只命中数据库一次:
from django.db.models import Q
user_inputed_codes = ['eN', 'De', 'FR']
lookup = Q()
for code in user_inputed_codes:
lookup |= Q(code__iexact=code)
filtered_products = Products.objects.filter(lookup)
不幸的是,正在查找的对象可以是小写或混合大小写,并且不可能限制这一点。我发现这很奇怪。至少在MySql上,查找中的_似乎不区分大小写。我看不出这有多优雅。Products.objects.all()可能返回数千行,然后您将在数据库之外对其进行筛选,然后将其作为列表返回,而不是作为查询返回,这意味着您无法(轻松)对其进行排序或对其执行其他筛选。我刚刚意识到你每次都在通过用户输入的\u数据\u作为\u列表
进行循环,所以是的,每个人,不要使用这种技术,除非你的表非常小。刚刚做了一个测试,你的方法对一个有30k+记录的表来说要花费大约200倍的时间:这是无效的,虽然你可以尝试使用生成器而不是简单的列表。你能再解释一下吗?我的意思是,如果你使用Django ORM系统的MYSQL数据库,那么所有的查询都不区分大小写。对于@Dietermemken,我用一个例子编辑了我的答案。
from django.db.models import Q
user_inputed_codes = ['eN', 'De', 'FR']
lookup = Q()
for code in user_inputed_codes:
lookup |= Q(code__iexact=code)
filtered_products = Products.objects.filter(lookup)