首页 文章

Python Django“和/或”在数据库中搜索

提问于
浏览
1

我有一个数据库设置,我希望设置搜索引擎,以便在搜索输入到不同搜索字段的所有内容时忽略空字段 . 现在我正在使用AND语句(“,”)和OR语句(“|”)的组合,但我不知道如何编写它来忽略空复选框和文本值,但只搜索填充的复选框和文本填写的框 . 我在views.py中的搜索代码是:

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)
                                        )

需要使用datepicker范围和国家/地区,然后其他所有内容都是OR语句 . 例如,如果该国家是美国,那么我希望它按州搜索,但如果该国家是加拿大,我希望它按省份搜索 . 如果两者都没有填写,我希望它忽略两者 .

现在,例如,如果我选择开始日期和结束日期,让国家/地区为美国并选择victim_1_name,它将返回日期范围内的所有内容,无论名称如何 . 如何在填写的字段中使用AND连接器时,如何忽略空白字段?

此外,“used_firearm”和“used_taser”之类的东西都是复选框,我的views.py用于读取这些字段:

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

这是否足以让它忽略复选框,如果它是空的,而传递一个“真”值,如果它被检查?

1 回答

  • 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 值) .

    您还应该研究像Haystack这样的专用搜索解决方案 .

相关问题