Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django : Can we use .exclude() on .get() in django querysets

Can we use

 MyClass.objects.get(description='hi').exclude(status='unknown')
like image 742
Shashank Hegde Avatar asked Aug 13 '13 06:08

Shashank Hegde


People also ask

What is the use of exclude in Django?

exclude() Returns a new QuerySet containing objects that do not match the given lookup parameters. The lookup parameters ( **kwargs ) should be in the format described in Field lookups below. Multiple parameters are joined via AND in the underlying SQL statement, and the whole thing is enclosed in a NOT() .

Why are QuerySets considered lazy?

This is because a Django QuerySet is a lazy object. It contains all of the information it needs to populate itself from the database, but will not actually do so until the information is needed.

How do I merge two QuerySets in Django?

Use union operator for queryset | to take union of two queryset. If both queryset belongs to same model / single model than it is possible to combine querysets by using union operator. One other way to achieve combine operation between two queryset is to use itertools chain function.


2 Answers

Your code works as expected if you do the exclude() before the get():

MyClass.objects.exclude(status='unknown').get(description='hi')

As @Burhan Khalid points out, the call to .get will only succeed if the resulting query returns exactly one row.

You could also use the Q object to get specify the filter directly in the .get:

MyClass.objects.get(Q(description='hi') & ~Q(status='unknown'))

Note that the Q object is only necessary because you use a .exclude (and Django's ORM does not have a not equal field lookup so you have to use .exclude).

If your original code had been (note that .exclude has been replaced with .filter):

MyClass.objects.filter(status='unknown').get(description='hi')

... you could simply do:

MyClass.objects.get(status='unknown', description='hi')
like image 119
codeape Avatar answered Oct 16 '22 21:10

codeape


You want instead:

MyClass.objects.filter(description='hi').exclude(status='unknown')

.get() will raise MultipleObjectsReturned if your query results in more than one matching set; which is likely to happen considering you are searching on something that isn't a primary key.

Using filter will give you a QuerySet, which you can later chain with other methods or simply step through to get the results.

like image 44
Burhan Khalid Avatar answered Oct 16 '22 23:10

Burhan Khalid