asprin
asprin

Reputation: 9833

django get_queryset() with conditional filter()

I have a custom model manager on model such as:

class MyCustomManager(models.Manager):
   def doFoo(self, user, s_format): 
        qs =  super().get_queryset().filter(created_by=user)
        return qs

which is returning data based on the user passed as the argument. However, how would I go about adding more AND conditions to the above query based on if conditions? Something like this:

class MyCustomManager(models.Manager):
       def doFoo(self, user, s_format): 
            qs =  super().get_queryset().filter(created_by=user)
            if <condition 1>:
                qs.filter(mode='A')
            elif <condition 2>:
                qs.filter(mode='B')
            return qs

If I do the above, even if <condition 2> is true, it's not generating created_by=1 AND mode='B' SQL

I'm basically trying to do the equivalent of the following but split by conditions

qs =  super().get_queryset().filter(created_by=user, mode='A')

Upvotes: 0

Views: 791

Answers (2)

Iain Shelvington
Iain Shelvington

Reputation: 32294

You need to reassign qs in your conditions

class MyCustomManager(models.Manager):
       def doFoo(self, user, s_format): 
            qs =  super().get_queryset().filter(created_by=user)
            if <condition 1>:
                qs = qs.filter(mode='A')
            elif <condition 2>:
                qs = qs.filter(mode='B')
            return qs

Upvotes: 2

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477608

.filter(…) [Django-doc] returns a new queryset, it does not alter qs itself, you thus should assign the result to qs again, or in this case return the queryset constructed by .filter(…):

class MyCustomManager(models.Manager):
    def doFoo(self, user, s_format): 
        qs = super().get_queryset().filter(created_by=user)
        if <condition 1>:
            return qs.filter(mode='A')
        elif <condition 2>:
            return qs.filter(mode='B')
        return qs

Upvotes: 1

Related Questions