0

From reading the documentation and this post here in SO, I understand that:

  • .filter(A, B) - means only rows that satisfy both A and B will be returned
  • .filter(A).filter(B) - means rows that satisfy either A or B will be returned

But I have situations where an admin may have the ability to access all, while a normal user's access will depend on other factors, which require additional filters to be added to the queryset. Another use case is an auto-complete view, which builds the base queryset (for all rows), then modifies it only if a search value was provided.

Here are a couple of examples:

    def get_queryset(self):
        user = self.request.user
        queryset = Client.objects \
            .select_related('country') \
            .prefetch_related('rates', 'tags', 'tags__tag')

        if self.view_type == 'archived':
            queryset = queryset.filter(status=StatusFieldModelMixin.Status.ARCHIVED)
        else:
            queryset = queryset.filter(status=StatusFieldModelMixin.Status.ACTIVE)

        if user.has_perm('access_all_clients', scope='global'):    # Custom has_perm method
            return queryset

        queryset = queryset.distinct() \
            .filter(
                Q(client_team_assignments__team_member__user=user) &
                Q(client_team_assignments__status=StatusFieldModelMixin.Status.ACTIVE)
            )
        return queryset
    def get_queryset(self):
        project_id = self.kwargs['pk'] if 'pk' in self.kwargs else None
        queryset = Sprint.objects.filter(project__id=project_id, status=StatusFieldModelMixin.Status.ACTIVE)

        search_key = self.kwargs['search_key'] if 'search_key' in self.kwargs else None
        if search_key:
            queryset = queryset.filter(name__icontains=search_key)
        return queryset

My question is, how do those subsequent queryset = queryset.filter(...) statements actually work? Is it an "AND", like .filter(A, B) or an "OR", like .filter(A).filter(B)? To add the subsequent filters, do I need to repeat the full queryset definition, instead of adding the filter to the existing queryset?

ExTexan
  • 373
  • 2
  • 18
  • 1
    The question you link has some answers that have misinformation, they make a statement that chained filters are ORing the queries. This is not true it's actually how the join is made. Normally you would find chained filters are the same as filtering with multiple arguments. It's only different in case of multi valued relationships. The answers on this question are more clear: [difference between filter with multiple arguments and chain filter in django](https://stackoverflow.com/questions/5542874/difference-between-filter-with-multiple-arguments-and-chain-filter-in-django) – Abdul Aziz Barkat Mar 03 '21 at 04:52
  • @AbdulAzizBarkat, thanks for that. If you post it as an answer, I'll accept it - even though you pretty much just referred me to another post, at least you found the one I didn't find. Cheers. – ExTexan Mar 03 '21 at 05:17
  • That would just be me copying other answers... Just enjoy :) – Abdul Aziz Barkat Mar 03 '21 at 05:18

0 Answers0