2010-03-02 96 views
4

在Django中幾乎所有的查找都有一個不區分大小寫的版本,除了它,看起來像。有沒有辦法在Django中進行不區分大小寫的IN查詢?

這是一個問題,因爲有時我需要做一個查找,我肯定案件會不正確。

Products.objects.filter(code__in=[user_entered_data_as_list]) 

我能做些什麼來解決這個問題嗎?有人提出一個黑客來解決這個問題?

+1

我覺得很奇怪。至少在MySql上,似乎__in查找是不區分大小寫的。 – 2012-08-11 06:06:44

回答

6

我通過使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) 
+0

+1儘管它不優雅:) – 2010-10-12 17:40:37

1

如果不會產生衝突,則在保存對象和filter時,可能的解決方法可能會將字符串轉換爲大寫或小寫字符串。

+0

不幸的是,被查找的對象可能是小寫字母或混合大小寫,並且不可能限制它。 – 2010-03-03 21:07:58

0

痘痘更優雅的方式將是這樣:

[x for x in Products.objects.all() if x.code.upper() in [y.upper() for y in user_entered_data_as_list]] 
+0

我不明白這是多麼優雅。 Products.objects.all()可能會返回*數千行,然後將其過濾到數據庫之外,然後將其作爲列表返回,而不是作爲查詢,這意味着您無法對其進行排序(很容易)或在其上執行額外的過濾器。剛剛意識到你每次都循環訪問'user_entered_data_as_list' *所以每個人都這樣做,除非你的表非常小,否則不要使用這種技術。 – 2012-09-24 15:14:32

+0

剛做了一個測試,你的方法需要用30k +記錄的表格長200倍左右:http://pastebin.com/R78P0Pdq – 2012-09-24 17:43:20

+0

雖然你可以嘗試使用生成器而不是簡單列表,但它並不有效。 – sepulchered 2012-10-12 10:45:26

1

這裏是不需要的情況下,準備DB值的解決方案。 此外,它在DB引擎端進行過濾,這意味着比在objects.all()上迭代更多的性能。

def case_insensitive_in_filter(fieldname, iterable): 
    """returns Q(fieldname__in=iterable) but case insensitive""" 
    q_list = map(lambda n: Q(**{fieldname+'__iexact': n}), iterable) 
    return reduce(lambda a, b: a | b, q_list) 

其他有效的解決方案是使用額外的有相當便攜原始SQL lower()功能:

MyModel.objects.extra(
    select={'lower_' + fieldname: 'lower(' + fieldname + ')'} 
).filter('lover_' + fieldname + '__in'=[x.lower() for x in iterable]) 
1

另一個解決方案 - 儘管原油 - 是包含原始字符串的不同情況列表「in」過濾器的參數。例如:不是['a','b','c'],而是使用['a','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 
1

如果你的數據庫是MySQL的,Django的治療在不區分大小寫查詢情況。雖然我不知道別人

編輯1:

model_name.objects.filter(location__city__name__in': ['Tokio','Paris',]) 

會給下面的結果在哪個城市的名字是

東京 TOKIO tokio or Paris 巴黎,巴黎

+0

你能多解釋一下嗎? – 2016-05-20 11:21:16

+0

我的意思是,如果您在Django ORM系統中使用MYSQL數據庫,那麼所有IN查詢都不區分大小寫。 – 2016-05-20 14:03:51

+0

去@DieterMeemken我用一個例子編輯了我的答案。 – 2016-05-20 14:11:57

相關問題