Search code examples
pythondjangodjango-viewsdjango-filter

Django filtering if an object has the specified value or is either isnull


I have a view that returns all the users that are either working in or are students in the school that the request.user owns, in my model's I have two fields works and learns that are foreignkey fields referencing the school object, when filtering the users to match the school that the request.user owns, I have to filter like something like so:

class AllUserList(generics.ListAPIView):
    permission_classes = [IsSchoolOwner, ]
    # queryset = User.objects.exclude(type__isnull=True)
    serializer_class = ListUsersSerializer

    def get_queryset(self):
        request = self.request.user
        if request.type == User.TYPES.OWNER:
            queryset = User.objects.filter(is_active=True,
                                           type__isnull=False, works__in=request.owns.all(), learns__in=request.owns.all())
        return queryset

there is an issue here as users that are working in the school will have the learns fields as null and the students will have the works field as null so how can I find if either of the fields matches and if they do make it ignores the other field.


Solution

  • You can specify a condition with a Q object [Django-doc] to define disjunctive conditions:

    class AllUserList(generics.ListAPIView):
        permission_classes = [IsSchoolOwner, ]
        model = User
        queryset = User.objects.all()
        serializer_class = ListUsersSerializer
    
        def get_queryset(self):
            user = self.request.user
            qs = super().get_queryset()
            if request.type == User.TYPES.OWNER:
                qs = qs.filter(
                    Q(works__in=user.owns.all()) | Q(learns__in=user.owns.all()),
                    is_active=True, type__isnull=False
                )
            return qs

    For more information, see the Complex lookups with Q objects section of the documentation.