Search code examples
djangodjango-querysetdjango-filter

Use QueryManager in Filter After SelectRelated


I'm trying to do select_related join in Django followed by a bunch of filtering.

queryset = Foo.foo_manager.all().select_related("bar").filter(
    bar__field_1__gt=0,
    bar__field_2=1,
    bar__field_3__lt=100,
    bar__field_4="X",
)

But the Bar class already has its own query manager called bar_manager that fetches all instances that match this condition. Is there a way to use this after the select_related? E.g.

 queryset = Foo.foo_manager.all().select_related("bar").filter(bar__bar_manager__all=True)

Solution

  • As far as I'm aware, this isn't possible. However, you could create a variable within the manager class that contains a group of Q() objects. You can then reuse the filter in other areas of your app like so:

    # managers.py
    
    class BarManager(models.Manager):
       BAR_FILTER = Q(field_1__gt=0) & Q(field_2=1) & ...
       
       def get_queryset(self):
          return super().get_queryset().filter(self.BAR_FILTER)
    

    And then in your views or wherever:

    from .managers import BarManager
    
    foo.bar_set.filter(BarManager.BAR_FILTER)