[Django]-How to group an array of objects by one of the model's attribute in Django?

2👍

You can use a custom ListSerializer (which we will set list_serializer_class to in the Meta of your serializer) and override its to_representation and use itertools.groupby to group your results:

from itertools import groupby

class HorseNutritionListSerializer(serializers.ListSerializer):
    def to_representation(self, data):
        ret = super().to_representation(data)
        return {key: list(group) for key, group in groupby(ret, key=lambda x: x['feeding_time'])}
    
    @property
    def data(self):
        ret = serializers.BaseSerializer.data.fget(self)
        return serializers.ReturnDict(ret, serializer=self)


class HorseNutritionSerializer(serializers.ModelSerializer):
    nutrition_measurement_id = serializers.ReadOnlyField(source = 'nutrition_measurement.name')
    nutrition_type_id = serializers.ReadOnlyField(source = 'nutrition_type.name')
    
    class Meta: 
        model = HorseNutrition
        fields = ['id', 'nutrition_measurement_id', 'nutrition_type_id', 'feeding_time']
        list_serializer_class = HorseNutritionListSerializer

Also for this grouping to be done properly your queryset must be ordered, which you can do in the view:

class HorseNutritionView(APIView):
    
    def get (self, request, format = None):
        #id = int(request.GET.get(self.lookup_url_kwarg))
        id = 1
        if id != None:
            queryset = HorseNutrition.objects.filter(horse_id = id).order_by('feeding_time')
            serializer = HorseNutritionSerializer(queryset, many = True)             
            return Response(serializer.data)
        else:
            return Response(status = status.HTTP_400_BAD_REQUEST)

Leave a comment