Search code examples
pythondjangodatabaseormdjango-orm

How Check ManyRelatedManager is None


-models.py

class Role:
    name = models.CharFiled(max_length=100)

    comp = models.ForeignKey(Company, models.CASCADE,
                             related_name="comp_roles")

    users = models.ManyToManyField(User, related_name='user_roles',
                                    related_query_name='user_role',
                                    through='UserRole')

class UserRole(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    role = models.ForeignKey(Role, on_delete=models.CASCADE)

based on certain conditions I have two queries

-in api_views.py:

1-Role.objects.filter(comp_id=self.comp_id).prefetch_related('users')

2-Role.objects.filter(comp_id=self.comp_id)

-RoleSerializer.py

class RoleSerializer(serializers.ModelSerializer):

    users = serializers.SerializerMethodField()

    def get_users(self, obj):

        #users: ManyRelatedManager = obj.users

        logger.info(f"this is obj.users: {obj.users}")
        logger.info(f"this is n obj.users: {obj.users == None}")

        # hit the db:
        # if not obj.users.all():
        # if obj.users.exists() == None:

        # no hit the db:
        # if obj.users.all() == None:
        # if obj.users == None:

        if obj.users.all() == None:
            logger.info(f"obj.users is None!")
            return None
        
        logger.info(f"obj.users is not None!")
        serializer = UserReadSerializer(obj.users.all(), many=True)
        return serializer.data
        

Either obj.users == None log or obj.users.all() == None codition are always false!

My question is how can I find out obj.users or obj.users.all() (in RoleSerializer/get_users) is None? so I can decide to return whether None or UserReadSerializer data.


Solution

  • obj.users.all() returns a queryset. so validating it against to None will not work. Instead you can use below line to get the count of entries and do your other operations on it.

    obj.users.count()
    

    if no users are present in the database for the model, it will return 0.

    Edit : Saw one more answer posted for this question now.

    obj.users.exists()
    

    using exists is efficient than getting the count

    Edit: Adding complete code .

    Views.py

    class RoleModelViewset(modelViewset):
        serializer_class = RoleSerializer
        queryset=Role.objects.filter(comp_id=self.comp_id).prefetch_related('users')
    

    Serializer.py

    class RoleSerializer(serializers.ModelSerializer):
    
        users = serializers.SerializerMethodField()
    
        def get_users(self, obj):
            if not obj.users.exists():
                logger.info(f"obj.users is None!")
                return None 
            logger.info(f"obj.users is not None!")
            serializer = UserReadSerializer(obj.users.all(), many=True)
            return serializer.data