составные наборы запросов django - PullRequest
2 голосов
/ 20 мая 2011

У меня есть этот механизм фильтрации, который работает, однако, он не очень элегантен.Должен быть лучший способ написать это.Мы будем благодарны за любые рекомендации.

Пользователь может выбрать один из нескольких фильтров для фильтрации списка:

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

Ответы [ 2 ]

2 голосов
/ 20 мая 2011
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
1 голос
/ 20 мая 2011

вы можете попробовать что-то вроде (не проверено)

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