Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django - filter after slice / filter on queryset where results have been limited

Tags:

python

django

having trouble understanding why I can't filter after a slice on a queryset and what is happening.

stuff = stuff.objects.all()
stuff.count()

= 7

If I then go

extra_stuff = stuff.filter(stuff_flag=id)
extra_stuff.count()

= 6. Everything is all good and I have my new queryset in extrastuff no issues

stuff = stuff.objects.all()[:3]
extra_stuff = stuff.filter(stuff_flag=id)

I get the error "Cannot filter a query once a slice has been taken."

How can I filter further on a queryset where I have limited the number of results?

like image 796
purchas Avatar asked Dec 14 '15 12:12

purchas


People also ask

Can I filter a QuerySet Django?

The filter() method is used to filter you search, and allows you to return only the rows that matches the search term.

How do I do a not equal in Django QuerySet filtering?

To do a not equal in Python Django queryset filtering, we can negate a equal with ~ . to call filter with the Q object negated with ~ to return all the Entry results that don't have id 3.

How can I filter a Django query with a list of values?

To filter a Python Django query with a list of values, we can use the filter method with in . to search Blog entries with pk set to 1,4 or 7 by calling Blog. objects. filter with the pk_in argument set to [1, 4, 7] .

What is the difference between filter and get method in Django?

Basically use get() when you want to get a single unique object, and filter() when you want to get all objects that match your lookup parameters.


1 Answers

You can't use filter() after you have sliced the queryset. The error is pretty explicit.

Cannot filter a query once a slice has been taken.

You could do the filter in Python

stuff = stuff.objects.all()[:3]
extra_stuff = [s for s in stuff if s.stuff_flag=='flag']

To get the number or items in extra_stuff, just use len()

extra_stuff_count = len(extra_stuff)

Doing the filtering in Python will work fine when the size of stuff is very small, as in this case. If you had a much larger slice, you could use a subquery, however this might have performance issues as well, you would have to test.

extra_stuff = Stuff.objects.filter(id__in=stuff, stuff_flag='flag')
like image 147
Alasdair Avatar answered Sep 22 '22 05:09

Alasdair