zoidberg
zoidberg

Reputation: 2199

Django: extend queryset or exclude from exclude method

I have a Django app where I need to combine two QuerySets, and disregard the exclude() filter only for certain items.

Here is an example of the model and the query.

class MyModel(models.Model):
    name = models.CharField(max_length=20)
    var1 = models.IntegerField()
    var2 = models.BooleanField()
    var3 = models.BooleanField()
    var4 = models.IntegerField()
    var5 = models.IntegerField()

qs1 = MyModel.objects.filter(var1__lte=10,var2=True).exclude(Q(var4=10) | Q(var5=20))

must_include_list = ['name1','name2','name3']

qs2 = MyModel.objects.filter(name__in=must_include_list)

I need to have a single queryset that does the filter and exclude from qs1, but also includes the rows from qs2 regardless of whether they match the qs1 filter and exclude.

I tried doing this:

qs1 = MyModel.objects.filter(Q(var1__lte=10,var2=True) | Q(name__in=must_include_list)).exclude(Q(var4=10| | Q(var5=20))

But it still applies the exclude to the must_include_list, so I miss some of the required entries.

Is there a way to tell the exclude() to not exclude the items in must_include_list, or is there a way to combine the two since querysets don't have an extend() method?

My solution based on bakkal's suggestion.

INCLUDE = Q(var1__lte=10,var2=True)
EXCLUDE = Q(var4=10) | Q(var5=20)
MUST_INCLUDE = Q(name__in=must_include_list)
FILTER = (INCLUDE & ~EXCLUDE) | MUST_INCLUDE
MyModel.objects.filter(FILTER).distinct()

Upvotes: 0

Views: 669

Answers (1)

bakkal
bakkal

Reputation: 55448

Let's rewrite

MyModel.objects.filter(var1__lte=10,var2=True).exclude(Q(var4=10) | Q(var5=20))

As

X = Q(var1__lte=10, var2=True) & ~(Q(var4=10) | Q(var5=20))
MyModel.objects.filter(X)

The other query is simply

Y = Q(name__in=must_include_list)

Now what you want is X or Y so

MyModel.objects.filter(X | Y)

Tip: if you rename X and Y to meaningful names, your code will become readable and clean, and less cryptic than reading the nested filter/exclude and logic operators

Upvotes: 1

Related Questions