I have models:
class User(models.Model):
...
group = models.ManyToManyField(
Group, related_name="users_group",
)
class Group(models.Model):
....
How to check in serializer is the Group empty (there is no relationship with User)
My version is :
class GroupSerializer(serializers.ModelSerializer):
empty = serializers.SerializerMethodField()
class Meta:
...
def get_empty(self, obj):
return not User.objects.filter(group=obj).exists()
But maybe there is an even better way.
>Solution :
If you define a ManyToManyModel [Django-doc], Django automatically defines one in reverse with the value for the related_name=… parameter [Django-doc] as name, so you can use:
class GroupSerializer(serializers.ModelSerializer):
empty = serializers.SerializerMethodField()
class Meta:
# …
def get_empty(self, obj):
return not group.users_group.exists()
But this is not very efficient if you want to serialize a large number of Groups: for each Group it will make an extra query. You can use a BooleanField:
class GroupSerializer(serializers.ModelSerializer):
empty = serializers.BooleanField()
class Meta:
# …
and then in the APIView or the ViewSet use as QuerySet a QuerySet where you make an annotation with an Exists subquery [Django-doc] to check if there exists a user for that Group:
from django.db.models import Exists, OuterRef
from rest_framework import viewsets
class MyModelViewSet(viewsets.ModelViewSet):
queryset = Group.objects.annotate(
empty=~Exists(
User.objects.filter(group=OuterRef('pk'))
)
)
# …