1

I need to group the result of a queryset by date on DRF

    """ Django model """
    class Matches(models.Model):
        name = models.CharField(max_length=100)
        platform = models.CharField(max_length=100)
        mode = models.CharField(max_length=100)
        kills = models.IntegerField()
        date = models.DateTimeField()

    """ Serializer """
    class MatchesSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Matches
            fields = ('name', 'platform', 'mode', 'kills', 'date')
    """ views """
    class Matches(generics.ListAPIView):
        serializer_class = serializers.MatchesSerializer
        filter_backends = (filters.OrderingFilter,)
        lookup_field = 'name'
        ordering = ('-date',)
        def get_queryset(self):
            username = self.kwargs['name']
            return models.Matches.objects.filter(name=username)

Desired output (just an example):

[
   {
      'date':'2019-01-01',
      'data':[
         {
            'platform':'ps4',
            'mode':'solo',
            'kills':10,
            'date':'2019-01-01 10:00:00'
         },
         {
            'platform':'ps4',
            'mode':'duo',
            'kills':10,
            'date':'2019-01-01 12:00:00'
         },
         {
            'platform':'ps4',
            'mode':'squad',
            'kills':10,
            'date':'2019-01-01 11:00:00'
         },

      ]
   },
   {
      'date':'2019-01-02',
      'data':[
         {
            'platform':'ps4',
            'mode':'solo',
            'kills':1,
            'date':'2019-01-02 10:00:00'
         },
         {
            'platform':'ps4',
            'mode':'duo',
            'kills':2,
            'date':'2019-01-02 12:00:00'
         },
         {
            'platform':'ps4',
            'mode':'squad',
            'kills':3,
            'date':'2019-01-02 11:00:00'
         },

      ]
   }
]

For me, the easy solution is to make a raw querie on django and create a serializer, but it feels not so pythonic...

So it appears that DRF has some beautiful way to make it look nice, maybe using to_representation...

fabriciols
  • 959
  • 1
  • 12
  • 25

2 Answers2

1

I used the itertools.groupby iterator. Check my code below.

from itertools import groupby

events = [["2020-04-01", "A"], ["2020-04-01", "B"], ["2020-04-02", "C"], ["2020-04-02", "D"]]

for k, g in groupby(events, lambda x: x[0]):
list = []
    for group in g:
        list.append(group[1])
    output[k] = list

The output will be grouped by date as follows

{'2020-04-01': ['A', 'B'], '2020-04-02': ['C', 'D']}

Please make sure your order by date first.

Nicolas
  • 156
  • 2
  • 2
0

You can use the function raw from Django ORM

results = Matches.objects.raw('SELECT * FROM myapp_matches GROUP BY date')
prosoitos
  • 6,679
  • 5
  • 27
  • 41
direyes
  • 53
  • 4