Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django filtering based on optional parameters

I have a list of optional parameters that I am using to filter in Django and am trying to come up with the best solution to apply these filters. My very first thought was to do something like:

if param_1 != 'all' and param_2 != 'all': # etc.
    class_var = ClassName.objects.filter(param_1__name=param_1, param_2__name=param_2) # etc.
else:
    class_var = ClassName.objects.all()

but since the parameters are all optional I might only want to filter based on param_1 and leave the rest set to 'all'. Of course the other option is to say something like:

class_var = ClassNam.objects.all()
if param_1 != 'all':
    class_var.filter(param_1__name=param_1)

if param_2 != 'all':
    class_var.filter(param_2__name=param_2)

# etc.

but that doesn't seem really efficient in my mind. I was just hoping to get some ideas on other ways I might be able to perform these option filters.

like image 866
DjangoNoob Avatar asked May 29 '15 20:05

DjangoNoob


2 Answers

You may want to look into Q objects. Briefly, the Q lets you use OR statements in your queries. From the aforelinked page:

Polls.objects.filter(
    Q(question__startswith='Who') | Q(question__startswith='What')
)

This will pull questions starting with "Who" OR "What".

like image 143
eykanal Avatar answered Oct 08 '22 12:10

eykanal


What you actually can do

from django.db.models import Q

q = Q()
if param_1 != 'all':
    q &= Q(param_1__name=param_1)

if param_2 != 'all':
    q &= Q(param_2__name=param_2)

class_var = ClassName.objects.filter(q)

OR

q = {}
if param_1 != 'all':
    q.update({'param_1__name': param_1})

if param_2 != 'all':
    q.update({'param_2__name': param_2})

class_var = ClassName.objects.filter(**q)
like image 20
Basalex Avatar answered Oct 08 '22 13:10

Basalex