views:

226

answers:

3

Hello,

I'm a Django newbie, so please forgive me if this is a stupid question. I have a search form that has multiple fields on it. I only wish to filter my queryset by those fields submitted that aren't empty. How do I do that? I'm aware you can chain querysets and Q objects together, but I don't know how to eliminate empty key/value pairs from the chain. I know the following doesn't work, but I thought it might provide insight into what I'm looking for. Thank you.

def art_search(request):
    if request.method == 'GET':
        form = AdvSearch(request.GET)
        if form.is_valid():
            art_name = form.cleaned_data['art_name']
            art_number = form.cleaned_data['art_number']
            artwork = Inventory.objects.filter(
                if art_name is not u'':
                    Q(marketingname=art_name),
                if art_number is not u'':
                    Q(marketingnumber=art_number)
            )
            return object_list(request, queryset=artwork)
    else:
        form = AdvSearch()
    return render_to_response('art/search.html', {
        'form': form,
    })
+2  A: 

You could write:

if form.is_valid():
    opts = {}
    for key in form.cleaned_data:
        if form.cleaned_data[key] != '':
            opts[key] = form.cleaned_data[key]
    artwork = Inventory.objects.filter(**opts)
    return object_list(request, queryset=artwork)

If filter parameters have the same names as form fields.

Dejw
A: 

Something simple I find is to create a dictionary like:

query_dict = { 'marketingname' : art_name , 'marketingnumber'=art_number}

Then exploiting python's kwargs syntax to pass it in nicely, i.e.

Inventory.objects.filter(**query_dict)

To build the initial dictionary you can use a list comprehension if your cleaned_data keys correspond to the parameters you're passing off to filter().

query_dict = dict([ (k,v) for k,v in form.cleaned_data.items() if v ])

But that doesn't seem to be the case here (markettingname != artname)

Koobz
I've written the same below first :/
Dejw
My answer isn't completely redundant. It demonstrates list comprehensions and dict(). Dziekuje :)
Koobz
A: 

you could try doing:

if art_name != '' and art_number != '':  
    artwork = Inventory.objects.filter(marketingname = art_name, marketingnumber = art_number)

even better if you use try

try:
    artwork = Inventory.objects.filter(marketingname = art_name, marketingnumber = art_number)
except:
    # do some error handling
EroSan