2013-10-18 38 views
1

我有一個數據庫設置,我希望設置搜索引擎,以便在搜索輸入到不同搜索字段的所有內容時忽略空字段。現在我正在使用AND語句(「,」)和OR語句(「|」)的組合,但我不確定如何編寫它以忽略空的複選框和文本值,但只搜索填充的複選框和文本。這是充滿我的搜索代碼在我的views.py箱子是:Python Django「和/或」在數據庫中搜索

incidents = Incident.objects.filter(
             Q(datepicker__range=[date_start, date_end]), 
             Q(country__contains=country), 
             Q(city__contains=city) 
             | Q(state__contains=state) 
             | Q(province__contains=province) 
             | Q(used_firearm__contains=firearm) 
             | Q(used_taser__contains=taser) 
             | Q(used_teargas__contains=teargas) 
             | Q(victim_1_name__contains=victim_name) 
             | Q(victim_1_ethnicity__contains=victim_ethnicity) 
             | Q(victim_1_age__contains=victim_age) 
             | Q(victim_1_sex__contains=victim_sex) 
             | Q(victim_1_status__contains=victim_status) 
             | Q(victim_1_armed__contains=victim_armed) 
             ) 

是必需的日期選擇範圍和國家,那麼其他的一切都是一個OR語句。例如,如果國家是美國,那麼我希望它按州進行搜索,但如果該國是加拿大,我希望它按省進行搜索。我想讓它忽略這兩個都沒有填寫。

現在,例如,如果我選擇開始日期和結束日期,請將該國家設爲美國並選擇victim_1_name,它將只返回所有日期範圍,不管名字。我如何讓它忽略空白字段,同時使用AND連接器填充字段?

而且,像「used_firearm」和「used_taser」是複選框,我閱讀這些領域views.py是:

if request.POST.get('used_teargas', False): 
       teargas    = request.POST['used_teargas'] 

那是足以讓它忽略複選框,如果它是空的,而通過如果選中了「真」值?

+1

您應該使用合適的搜索引擎進行研究,例如[solr](http://lucene.apache.org/solr/) –

+0

在將列表傳遞給過濾器對象之前,先在列表中構建您的搜索選項,應用設置的選項。 –

回答

2

也許是這樣的:

text_fields = { 
    'city': request.POST.get('city'), 
    'state': request.POST.get('state'), 
    'province': request.POST.get('province'), 
    'used_teargas': request.POST.get('teargas'), 
    'victim_1_name': request.POST.get('victim_name'), 
    'victim_1_ethnicity': request.POST.get('victim_ethnicity'), 
    'victim_1_age': request.POST.get('victim_age'), 
    'victim_1_sex': request.POST.get('victim_sex'), 
    'victim_1_status': request.POST.get('victim_status'), 
} 

boolean_fields = { 
    'used_taser': request.POST.get('taser'), 
    'used_teargas': request.POST.get('teargas'), 
    'victim_1_armed': request.POST.get('victim_armed') 
} 

q_objects = Q() 

for field, value in text_fields.iteritems(): 
    if value: 
     q_objects |= Q(**{field+'__contains': value}) 

for field, value in boolean_fields.iteritems(): 
    if value: 
     q_objects |= Q(**{field: True}) 

incidents = Incident.objects.filter(
    Q(datepicker__range=[date_start, date_end]), 
    Q(country__contains=country), 
    q_objects 
) 

結果查詢是非常相似的,你提供的一個,唯一不同的是列表或or ED(|Q對象(命名爲q_objects這裏)是動態生成的 - 允許您提供有關是否應在該列表中包含特定字段的規則(在該特定情況下爲「if value」,這將完全按照您的要求進行 - 過濾掉空字符串,False值和None值。

您還應該尋找專門的搜索解決方案,如。

+0

感謝您的幫助!這比我寫的要短得多。我計劃研究Haystack和Solr搜索插件,我只想自己寫一些東西,這樣我就能理解它們是如何工作的。但有一個問題 - 除了我的複選框之外,其他所有方面都適用。我將它們設置爲模型中的BooleanField,但是當我在搜索字段中選擇一個時,它不起作用。儘管如此,所有其他搜索字段都有效。我需要告訴它爲複選框尋找不同的值嗎? –

+0

我添加了一個使用'bool()'來確保你得到一個邏輯值的例子。 –

+0

嗯我很困惑,它仍然無法正常工作。 bool(request.POST.get('victim_armed'))會返回一個我想在Q中使用的值(** {field +'__ contains':value})還是我想要使用類似Q(** {field +'__ isnull':value})?當我檢查我的sqlite數據庫時,它告訴我複選框值保存爲0或1,但是當我將{{incident.victim_armed}}放入我的模板中時,它會輸出True或False。我是否應該對複選框使用單獨的Q搜索,還是對模型有更深的問題?複選框HTML是