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?