2011-05-20 114 views
2

我有這個過濾機制,但是,它不是很優雅。必須有更好的方式來寫這個。任何建議將不勝感激。django複合查詢集

用戶能夠從多個過濾器選擇過濾列表:

forms.py

class FilterForm(forms.Form): 
    def __init__(self, *args, **kwargs): 
     super(FilterForm, self).__init__(*args, **kwargs) 
     self.fields['group'].widget.attrs["onchange"] = mark_safe('this.form.submit();') 
     self.fields['location'].widget.attrs["onchange"] = mark_safe('this.form.submit();') 
     self.fields['host'].widget.attrs["onchange"] = mark_safe('this.form.submit();') 
     self.fields['exchange'].widget.attrs["onchange"] = mark_safe('this.form.submit();') 
    group = forms.ModelChoiceField(queryset=Group.objects.all().order_by('name'),) 
    location = forms.ModelChoiceField(queryset=Location.objects.all().order_by('name'),) 
    host = forms.ModelChoiceField(queryset=Host.objects.all().order_by('name'),) 
    exchange = forms.ModelChoiceField(queryset=Exchange.objects.all().order_by('name'),) 

views.py

initial = {} 
#check for filtering 
if 'group' in request.POST: 
    if request.POST['group']: 
     initial['group'] = request.POST['group'] 
     obj = Group.objects.get(pk=request.POST['group']) 
     selectForm.fields['job'].queryset = selectForm.fields['job'].queryset.filter(group=obj) 
if 'host' in request.POST: 
    if request.POST['host']: 
     initial['host'] = request.POST['host'] 
     obj = Host.objects.get(pk=request.POST['host']) 
     selectForm.fields['job'].queryset = selectForm.fields['job'].queryset.filter(host=obj) 
if 'location' in request.POST: 
    if request.POST['location']: 
     initial['location'] = request.POST['location'] 
     obj = Location.objects.get(pk=request.POST['location']) 
     selectForm.fields['job'].queryset = selectForm.fields['job'].queryset.filter(colo=obj) 
if 'exchange' in request.POST: 
    if request.POST['exchange']: 
     initial['exchange'] = request.POST['exchange'] 
     obj = Exchange.objects.get(pk=request.POST['exchange']) 
     selectForm.fields['job'].queryset = selectForm.fields['job'].queryset.filter(exchange=obj) 

filterForm.initial = initial 

回答

1

你可以嘗試一些沿(未經測試)

options = {'group':Group, 'host':Host, 'location':Location, 'exchange':Exchange} 
for key, modelclass in options.items(): 
    value = request.POST.get(key, None) 
    if value: 
     initial[key] = value 
     obj = modelclass.objects.get(pk=value) 
     filter = {} 
     filter[key] = obj 
     selectForm.fields['job'].queryset = selectForm.fields['job'].queryset.filter(**filter) 
+0

我不認爲它適用於位置字段。該過濾器需要過濾器(colo = obj)而不是位置= obj – 2011-05-20 15:17:15

+0

大壩沒有發現「colo」不同。 – JamesO 2011-05-20 15:21:56

+0

這樣一個奇怪的名字爲一個位置fkey字段 – 2011-05-20 15:22:30

2
initial = dict(request.POST) 
# The dictionary key is the field name retrieved from the POST request 
# The first list item is the model to query 
# The second list item is the "jobs" field to query 
dict_models = {'group': [Group, 'group']], 
    'host': [Host, 'host'], 
    'location': [Location, 'colo'], 
    'exchange': [Exchange, 'exchange'], 
    } 

#check for filtering 
for k, v in dict_models.items(): 
    if initial.get(k, None): 
     obj = v[0].objects.get(pk=initial[k]) 
     kwargs = v[1] 
     for key in kwargs.keys: 
      kwargs[key] = obj 
     selectForm.fields['job'].queryset = selectForm.fields['job'].queryset.filter(**kwargs) 

filterForm.initial = initial 
+0

我沒有結婚到colo fKey。我將其在我的模型中重命名爲位置。謝謝! – nnachefski 2011-05-20 15:28:48

+1

好的命名:P – 2011-05-20 15:38:06