2013-12-15 6 views
-1

사용자가 여러 옵션을 선택할 수있는 양식을 만들고 쿼리에서 필터를 결과로 만들었습니다. 예를 들어 사용자는 초기 양식의 소매점, 레스토랑과 같은 하나 이상의 비즈니스 수직 계열을 선택할 수 있습니다. 두 번째 양식에서는 클라우드, 전제 등의 소프트웨어 구현을 선택할 수 있습니다 ... 쿼리를 작성하는 기타 필드 결과를 필터링합니다. 폼의 각 섹션 (industry, deployment_model) 값은 값을 가질 수도 있고 그렇지 않을 수도 있습니다.request.GET에서 동적으로 필터를 생성합니다.

일부 오류가있는 부분적으로 작동하는 필터가 있습니다. 예를 들어, "industry"섹션의 값이있는 양식을 제출하면 양식 결과에 설정된 초기 체크 박스가 반환됩니다.

[<django.db.models.query_utils.Q object at 0x7f6b60b854d0>] 

그러나 양식의 마지막 섹션에만 값을 제출하면 제대로 작동하고 결과가 예상대로 반환됩니다.

def software_list(request): 

    if request.method == 'GET': 
     result = [] 
     if 'industry' in request.GET and 'industry' is not None: 
      formattedq = request.GET 
      #QueryDict instance is immutable so we need to make a copy 
      formattedq = formattedq.copy() 
      formattedq = formattedq.getlist('industry') 
      softquery = Q(industries__id__in=[ind for ind in formattedq]) 
      #debugformattedq = formattedq 
      result.append(softquery) 

     if 'deployment_model' in request.GET: 
      formattedq = request.GET 
      #QueryDict instance is immutable so we need to make a copy 
      formattedq = formattedq.copy() 
      formattedq = formattedq.getlist('deployment_model') 
      depquery = Q(deploymentmodels__id__in=[ind for ind in formattedq]) 
      #debugformattedq = formattedq 
      result.append(depquery) 

      result = Software.objects.filter(reduce(operator.and_, result)) 
    else: 
     SoftwareSearchForm() 
    return render_to_response('software_list.html', 
     { 
     #'software_list':results, 
     'SoftwareSearchForm':SoftwareSearchForm, 
     'formattedq':result, 
     }, 
     context_instance = RequestContext(request) 
     ) 

    return render_to_response('software_list.html', {'SoftwareSearchForm':SoftwareSearchForm}) 


<form action="" method="get" id="filterform"><div style='display:none'><input type='hidden' name='csrfmiddlewaretoken' value='adsfasf' /></div> 
<p><label for="id_industry_0">Industry:</label> <ul> 
<li><label for="id_industry_0"><input type="checkbox" name="industry" value="8" id="id_industry_0" /> clothing</label></li> 
<li><label for="id_industry_1"><input type="checkbox" name="industry" value="7" id="id_industry_1" /> food</label></li> 
<li><label for="id_industry_2"><input type="checkbox" name="industry" value="5" id="id_industry_2" /> Apparel</label></li> 
<li><label for="id_industry_3"><input type="checkbox" name="industry" value="9" id="id_industry_3" /> food truck</label></li> 
<li><label for="id_industry_4"><input type="checkbox" name="industry" value="6" id="id_industry_4" /> Bar/Night Club</label></li> 
</ul></p> 
<p><label for="id_deployment_model_0">Deployment model:</label> <ul> 
<li><label for="id_deployment_model_0"><input type="checkbox" name="deployment_model" value="4" id="id_deployment_model_0" /> On Premise</label></li> 
<li><label for="id_deployment_model_1"><input type="checkbox" name="deployment_model" value="6" id="id_deployment_model_1" /> Software as a Service</label></li> 
<li><label for="id_deployment_model_2"><input type="checkbox" name="deployment_model" value="8" id="id_deployment_model_2" /> server</label></li> 
<li><label for="id_deployment_model_3"><input type="checkbox" name="deployment_model" value="5" id="id_deployment_model_3" /> Cloud</label></li> 
<li><label for="id_deployment_model_4"><input type="checkbox" name="deployment_model" value="7" id="id_deployment_model_4" /> premise</label></li> 
</ul></p> 
<input type="submit" value="Submit" /> 
</form> 
+0

내가 혼란 스러워요, 당신의 질문은 무엇입니까? 양식 마법사를 만들겠습니까? 최종 결과를 어떻게 보이시겠습니까? – yuvi

+0

기본적으로 result = Q (deploymentmodels__id__in = [ind에 대한 ind 형식의] 및 Q (deploymentmodels__id__in = [ind 형식의 q에 대한 ind]))와 같은 ANDed Q 쿼리를 구성해야합니다. – shaytac

+0

[formsets 사용] (https : //docs.djangoproject.com/en/dev/topics/forms/formsets/#formsets)? – yuvi

답변

0

귀하의 문제는 결과가 2 개 가능한 값을 저장할 수있는 것 같다. Q 개체 또는 쿼리 집합의 목록입니다. software_list보기에서 결과는 쿼리 세트로 덮어 쓰지만, deploy_model 매개 변수가 설정된 경우에만 결과를 덮어 씁니다. result = Software.objects.filter(reduce(operator.and_, result))은 한 번에 여러 번 들여 쓰입니다. 그리고 오직 산업을 공급할 때 그러한 것은 건너 뜁니다.

예 :

if 'deployment_model' in request.GET: 
     ... 
     result.append(depquery) 

     result = Software.objects.filter(reduce(operator.and_, result)) 

은 다음과 같아야합니다 문자열 때문에 if 'industry' in request.GET and 'industry' is not None: :

def software_list(request): 

    if request.method == 'GET': 
     result = [] 
     if 'industry' in request.GET and 'industry' is not None: 
      formattedq = request.GET 
      #QueryDict instance is immutable so we need to make a copy 
      formattedq = formattedq.copy() 
      formattedq = formattedq.getlist('industry') 
      softquery = Q(industries__id__in=[ind for ind in formattedq]) 
      #debugformattedq = formattedq 
      result.append(softquery) 

     if 'deployment_model' in request.GET: 
      formattedq = request.GET 
      #QueryDict instance is immutable so we need to make a copy 
      formattedq = formattedq.copy() 
      formattedq = formattedq.getlist('deployment_model') 
      depquery = Q(deploymentmodels__id__in=[ind for ind in formattedq]) 
      #debugformattedq = formattedq 
      result.append(depquery) 

     result = Software.objects.filter(reduce(operator.and_, result)) 
    else: 
     SoftwareSearchForm() 
    return render_to_response('software_list.html', 
     { 
     #'software_list':results, 
     'SoftwareSearchForm':SoftwareSearchForm, 
     'formattedq':result, 
     }, 
     context_instance = RequestContext(request) 
     ) 

    return render_to_response('software_list.html', {'SoftwareSearchForm':SoftwareSearchForm}) 

또한 if 문에 작은 결함이있다 :

if 'deployment_model' in request.GET: 
     ... 
     result.append(depquery) 

    result = Software.objects.filter(reduce(operator.and_, result)) 

여기에 온 방법이다 '산업'은 절대로 없음. (덕분에 조 홀로 웨이)

if 'industry' in request.GET and request.GET['industry'] is not None: 

또는 단순화 : 당신은 아마 사용하는 의미

if request.GET.get('industry') is not None: 
+1

마지막 문장에서, request.GET [ 'industry']'는 키가 존재하지 않으면 예외를 던질 것입니다. 나는 당신이'request.GET.get ('industry')를 의미한다고 생각한다. 키가 존재하지 않는다면 디폴트로'None'을 리턴한다. –

+1

왼쪽에서 오른쪽으로 평가하면 왼쪽 부분이 실패 할 경우 AND의 오른쪽 부분이 수행되지 않습니다. 나는. '업계'가 요청할 수 있습니다 .GET을 통해 '업계'가 평가되면 (비어있을 수 있음) '업계'가 존재하도록 할 것입니다. – EWit

+1

그래, 그건 사실이야. 나는 당신이 전체 라인을 그 라인으로 대체 할 것을 제안하고 있다고 생각했습니다. 어쨌든, 그렇게하면 사전에 두 개의 해시 검색이 필요합니다.'request.GET.get ('industry')'로 압축하면 해쉬 룩업을 제거하고 문장을 간소화 할 수 있습니다. –

관련 문제