[Answered ]-Queryset with collated/merged values

1👍

Without making use of a database-specific feature, you can work with a Prefetch object [Django-doc]:

from django.db.models import Prefetch

class ParentSearchByChildNameView(generics.ListAPIView):
    """
    Return a list of parents who have a child with the given name
    """
    serializer_class = ParentSerializer

    def get_queryset(self):
        child_name = self.request.query_params.get('name')
        return = Parent.objects.filter(
            children__name__contains=child_name
        ).prefetch_related(
            Prefetch('children', Child.objects.filter(name=child_name), to_attr='matched_children')
        ).distinct()

For the serializer we then can work with a PrimaryKeyRelatedField [drf-doc]:

class ParentSerializer(serializers.ModelSerializer)
    matched_children = serializers.PrimaryKeyRelatedField(
        many=True,
        read_only=True
    )

    class Meta:
        model = Parent
        fields = ['url', 'name', 'matched_children']

0👍

If you work with , you can work with an ArrayAgg expression [Django-doc]:

from django.contrib.postgres.aggregates import ArrayAgg

class ParentSearchByChildNameView(generics.ListAPIView):
    """
    Return a list of parents who have a child with the given name
    """
    serializer_class = ParentSerializer

    def get_queryset(self):
        child_name = self.request.query_params.get('name')
        return = Parent.objects.filter(
            children__name__contains=child_name
        ).annotate(matched_children=ArrayAgg('children__pk'))

In the serializer you thus add a ListField that will list the children with:

class ParentSerializer(serializers.ModelSerializer)
    matched_children = serializers.ListField(
        child=serializers.IntegerField(),
        read_only=True
    )

    class Meta:
        model = Parent
        fields = ['url', 'name', 'matched_children']

Leave a comment