64
You can chain queries:
user = User.objects.get(pk=1)
category = Category.objects.get(pk=1)
qs = Item.objects.filter(user=user, date=now())
if category:
qs = qs.filter(category=category)
As queryset are executed lazily, DB hit will occur only when you display items.
18
They are several approach to your issue. One approach is to play with Complex lookups with Q objects
from django.db.models import Q
user = User.objects.get(pk=1)
category = Category.objects.get(pk=1)
f1 = Q( user=user, date=now() )
f_cat_is_none = Q( category__isnull = True )
f_cat_is_not_none = Q( category=category )
todays_items = Item.objects.filter( f1 & ( f_cat_is_none | f_cat_is_not_none ) )
I don’t right understand in your answer if this is the query you are looking for, but, with this example you can compose easily your own query.
Edited due OP comment
category__isnull == True
means that, in database, the item has not an associated category.
Perhaps the query you are looking for is:
from django.db.models import Q
user_pk = 1
category_pk = 1 #some times None
f = Q( user__pk = user_pk, date=now() )
if category_pk is not None:
f &= Q( category__pk = category_pk )
todays_items = Item.objects.filter( f )
This is only a code sample, fit it to your requirements. Be careful with single _
and double __
.
- [Django]-Error trying to install Postgres for python (psycopg2)
- [Django]-How can I disable logging while running unit tests in Python Django?
- [Django]-A field with precision 10, scale 2 must round to an absolute value less than 10^8
11
Well, this is rather old question but for those who would like to do the conditional filtering on one line, here is my approach (Btw, the following code can probably be written in a more generic way):
from django.db.models import Q
def conditional_category_filter(category):
if category != None:
return Q(category=category)
else:
return Q() #Dummy filter
user = User.objects.get(pk=1)
category = Category.objects.get(pk=1)
todays_items = Item.objects.filter(conditional_category_filter(category), user=user, date=now())
The only thing you need to watch is to use the conditional_category_filter(category)
call before the keyword arguments like user=user
. For example the following code would throw an error:
todays_items = Item.objects.filter(user=user, date=now(), conditional_category_filter(category))
- [Django]-How do I call a Django function on button click?
- [Django]-Django Serializer Method Field
- [Django]-Django URLs TypeError: view must be a callable or a list/tuple in the case of include()
4
To continue on @iuysal answer:
To make it generic you need to pass the key too as parameter, to do that you need to pass a dictionary, here’s how I did it:
Create your dictionary like this:
filters = {'filter1': 'value1', 'filter2__startswith': 'valu', ...}
Then pass it to your Item filters like this:
Item.objects.filter(*[Q(**{k: v}) for k, v in filters.items() if v], filter3='value3')
The first version less cryptic version I had:
def _filter(filters):
filters = []
for k, v in n.items():
if v:
filters.append(Q(**{k: v}))
return filters
filters = _filter({'name': name})
return Item.objects.filter(*filters)
Unpacking explanation: We want to give Q (queries)
as args
to objects.filter
as args while we want to give kwargs
to Q()
I have this on production now (I will just modify the filters names because it’s sensitive):
def get_queryset(self):
filter1 = self.request.GET.get('filter1 ', '')
filter2__startswith = self.request.GET.get('filter2_prefix ', '')
def filters_to_Qs(filters):
return [Q(**{k: v}) for k, v in filters.items() if v]
filters = {'filter1': filter1 ,
'filter2__startswith': filter2__startswith }
return Order.objects.filter(*filters_to_Qs(filters))
- [Django]-How to execute a Python script from the Django shell?
- [Django]-Django "You have unapplied migrations". Which ones?
- [Django]-Access web server on VirtualBox/Vagrant machine from host browser?
1
from django.db.models import Q
qs = Users.objects.filter(
p_id=parent_id,
status=True
).all()
if user_id>0:
qs = qs.filter( ~Q(id=user_id) )
in
qs
we will get the filtered results
- [Django]-Django admin and MongoDB, possible at all?
- [Django]-Set language within a django view
- [Django]-In the Django admin interface, is there a way to duplicate an item?