2013-12-15 29 views
-1

構建一個過濾器我建立一個表格,用戶可以選擇多個選項和查詢內置過濾器的結果。例如用戶可以選擇一個或多個業務垂直,如零售,初步形成對餐館,他們可以選擇執行這可能是雲軟件的第二個形式,在前提等等,更等領域構建查詢過濾結果。在表格的每個部分(行業,deployment_model)的值可能會或可能不會有值動態地從request.GET中

我得到了過濾器的一些錯誤部分工作。例如,如果我提交表單的「行業」部分的值是在返回的表單結果上設置的初始複選框;

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

它應該基本上構造一個ANDED Q查詢,例如result = Q(deploymentmodels__id__in = [IND for formattedq]&Q(deploymentmodels__id__in = [ind for ind in formattedq])) – shaytac

+0

您是否熟悉[using formsets](https: //docs.djangoproject.com/en/dev/topics/forms/formsets/#formsets)? – yuvi

回答

0

您的問題似乎是,結果可以容納2倍可能的值。 Q對象或查詢集列表。 在software_list查看您覆蓋與查詢集造成的,但只有當deployment_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 'deployment_model' in request.GET: 
     ... 
     result.append(depquery) 

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

這裏是整個方法:

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 'industry' in request.GET and 'industry' is not None:由於字符串'行業'永遠不會是無。你可能想用的是:

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

或簡化(感謝喬·霍洛韋):

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

在你的最後一句話,'request.GET中[「產業」]'將如果該鍵不存在拋出異常。我認爲你的意思是'request.GET.get('industry')',如果密鑰不存在,默認返回'None'。 –

+1

從左到右評估將阻止AND的右側部分在左側部分失敗時執行。即'行業'的要求.GET將確保「行業」將在評估時出現(可能爲空)。 – EWit

+1

好的,那是真的。我以爲你提議用這個替換整條線。無論如何,這樣做將需要字典中的兩個哈希查找。如果你將它壓縮到'request.GET.get('industry')',你可以消除哈希查找並簡化語句。 –