2014-04-09 3 views
0

사용자가 1,2 또는 모두 (이 경우 3 개) 검색 필터를 입력 할 수있는 검색 양식을 준비하려고합니다.여러 개의 키로 장고 검색 개체

검색 필터는 다음과 같습니다 : 성, 전화 및 주소. 쿼리 세트를 필터링하려고합니다 :

if filterForm.is_valid(): 
    last_name = filterForm.cleaned_data.get('last_name') 
    phone= filterForm.cleaned_data.get('phone') 
    address = filterForm.cleaned_data.get('address') 

    if last_name is None and phone is None and address is None: 
     pass 
     #we dont do search id db 
    else: 
     clients = Client.objects.filter(Q(last_name__contains=last_name) | Q(phone=phone) | Q(address__contains=address)) 

각 검색 키가 비어있을 수 있습니다.

불행히도 예상보다 많은 결과를 반환합니다. 성 필드로 검색 필터 "예"를 입력하면이 성이있는 필드와 많은 다른 행이 반환됩니다.

이 검색 문제를 해결하는 방법을 알려주세요.

답변

1

공백 키가 값이있는 모든 행과 일치하므로 검색 키 중 하나라도 비어있는 경우 검색 결과가 예상보다 많은 것으로 나타납니다.

값이있는 키만 필터링하면 더 잘 작동합니다. 위의 코드는 동적 쿼리에 추가되어야 필터를 추가합니다

if filterForm.is_valid(): 
    last_name = filterForm.cleaned_data.get('last_name') 
    phone= filterForm.cleaned_data.get('phone') 
    address = filterForm.cleaned_data.get('address') 

    import operator 

    predicates = [] 

    if last_name: 
     predicates.append(Q(last_name__contains=last_name)) 
    if phone: 
     predicates.append(Q(phone=phone)) 
    if address: 
     predicates.append(Q(address__contains=address)) 

    if len(predicates) == 0: 
     # Nothing to search for 
     pass 
    else: 
     clients = Client.objects.filter(reduce(operator.or_, predicates)) 

:

여기에 그것을 할 수있는 방법의 한 예입니다. oprator.or_을 사용하면 OR (= 적어도 하나의 명령문을 충족해야 함)으로 연결됩니다. 대신 모든 문장을 만족 시키려면 대신 operator.and_을 사용할 수 있습니다.