How can I make a list of group data by month-year in rest Framework with json output?

github logo ・1 min read

The json data format I want like this:

[
  {
    monthName: "AUG 2019",
    items: [
      {
        day: "03",
        description: "Baseball",
      },
      {
        day: "08",
        description: " Baseball 2"
      },

    ]
  },
  {
    monthName: "Sep 2019",
    items: [
      {
        day: "03",
        description: "Baseball",
      },
      {
        day: "08",
        description: " Baseball 2"
      },

    ]
  }
]
twitter logo DISCUSS (11)
markdown guide
 

i have a solution that I've tried and worked for me.

models.py


class Item(models.Model):

    time = models.IntegerField()
    description = models.CharField(max_length=50)

class GroupData(models.Model):

    item = models.ForeignKey(Item, related_name='items', on_delete=models.CASCADE)

    date = models.DateField()

serilizer.py


import datetime
class GroupDataSerializer(serializers.ModelSerializer):

    date = serializers.SerializerMethodField(method_name='get_date')
    class Meta:
        model = GroupData
        fields =('__all__')

    def get_date(self, instance):
        date = datetime.datetime.now()
        return date.strftime("%m/%d/%Y")

views.py


class GroupDataView(generics.ListAPIView):

    queryset = GroupData.objects.all()
    serializer_class = GroupDataSerializer
    
    def get_queryset(self):
        queryset = self.queryset

        return queryset.objects.filter(data=id).order_by('-date')

hope it works for you. DM me if you have a problem

 

My Model Is

class Event(models.Model):
title = models.CharField(max_length=255, default=None, unique=True)
description = models.TextField()
date = models.DateField(default=None, null=True)

I want to group the from the date field with month-year( like 01-2017 or JAN-2017)

I see that you created another model for that. Can I do it with single model?

 

yeah you can but as a best practice if you have a data that require more than one field just put it in a class and refer to it as a foreign key

so it will be a class for your event that have date and name
and a class for group of event or category that take events as foreign keys
in django admin you can control that easily

Ok. Let me try this. If it is worked that would be great

 

It's not working for me.


return queryset.objects.filter(data=id).order_by('-date')

where you get the data=id?


date = datetime.datetime.now()
return date.strftime("%m/%d/%Y")

I need the date from date field. Not from the datetime.now()

 

okay the id is a field that django auto add in your model as a primary key you can made you custom primary key look in the documentation.

ah so you need to delete the datetime.now and just return the date forma from you model it should look like this

return instance.date.strftime("%m/%d/%Y")

change the date variable by you varibale name

 

Here are my codes

models.py

class Event(models.Model):
    title = models.CharField(max_length=255, default=None, unique=True)
    link = models.URLField(default=None, null=True)
    description = models.TextField()

    def __str__(self):
        return self.title

    class Meta:
        db_table = 'events'

class EventGroup(models.Model):
    event = models.ForeignKey(Event, related_name='events', on_delete=models.CASCADE)
    event_date = models.DateField()

    class Meta:
        db_table = 'event_group'

views.py

class EventGroupData(ListAPIView):
    queryset = EventGroup.objects.all()
    serializer_class = EventGroupSerializer

    def get_queryset(self):
        queryset = self.queryset

        return queryset.objects.filter(data=id).order_by('-event_date')

Serializer.py

import datetime
class EventGroupSerializer(serializers.ModelSerializer):
    event_date = serializers.SerializerMethodField(method_name='get_date')
    class Meta:
        model = EventGroup
        fields = '__all__'

    def get_date(self, instance):
        event_date = datetime.datetime.now()
        return event_date.strftime("%m/%d/%Y")
 

can you please tell me why same month showing twice with same data?
models.py

class Event(models.Model):
    title = models.CharField(max_length=255, default=None, unique=True)
    link = models.URLField(default=None, null=True)
    description = models.TextField()
    date = models.DateField(default=None, null=True)
    is_published = models.BooleanField(default=False)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.title

    class Meta:
        db_table = 'events'
        verbose_name = 'event'
        verbose_name_plural = 'events'

class EventGroup(models.Model):
    event = models.ForeignKey(Event, related_name='events', on_delete=models.CASCADE)
    date = models.DateField()
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    class Meta:
        db_table = 'event_group'

serializer.py

class EventGroupSerializer(serializers.ModelSerializer):
    events = serializers.SerializerMethodField(method_name='get_events')
    month_year = serializers.SerializerMethodField(method_name='get_month_year')

    total = serializers.SerializerMethodField(method_name='get_count_events')
    class Meta:
        model = EventGroup
        fields = ('month_year', 'total', 'events',)

    def get_count_events(self, instance):
        org_date = str(instance['date'])
        date = datetime.datetime.strptime(org_date, "%Y-%m-%d")
        month = date.month
        year = date.year
        count = Event.objects.filter(date__month=month, date__year=year).count()
        return count

    def get_month_year(self, instance):
        org_date = str(instance['date'])
        date = datetime.datetime.strptime(org_date, "%Y-%m-%d").date()
        month_year = str(date.month)+'-'+str(date.year)
        return str(month_year)

    def get_events(self, instance):
        org_date = str(instance['date'])
        date = datetime.datetime.strptime(org_date, "%Y-%m-%d")
        month = date.month
        year = date.year
        events = Event.objects.filter(date__month=month, date__year=year)
        event_serializer = EventSerializer(events, many=True)
        return event_serializer.data

views.py

class EventGroupData(ListAPIView):
    queryset = EventGroup.objects.all()

    serializer_class = EventGroupSerializer


    def get_queryset(self):
        queryset = self.queryset

        return queryset.annotate(month=TruncMonth('date')).values('date').annotate(c=Count('id')).order_by()

results

{
    "count": 4,
    "next": null,
    "previous": null,
    "results": [
        {
            "month_year": "6-2019",
            "events": [
                {
                    "id": 30,
                    "title": "Event 2",
                    "description": "Event 2",
                    "date": "2019-06-02"
                },
                {
                    "id": 31,
                    "title": "Event 3",
                    "description": "Event 3",
                    "date": "2019-06-04"
                }
            ]
        },
        {
            "month_year": "6-2019",
            "events": [
                {
                    "id": 30,
                    "title": "Event 2",
                    "description": "Event 2",
                    "date": "2019-06-02"
                },
                {
                    "id": 31,
                    "title": "Event 3",
                    "description": "Event 3",
                    "date": "2019-06-04"
                }
            ]
        },
        {
            "month_year": "9-2019",
            "events": [
                {
                    "id": 32,
                    "title": "Event 4",
                    "description": "Event 4",
                    "date": "2019-09-04"
                },
                {
                    "id": 29,
                    "title": "Event 1",
                    "description": "Event 1",
                    "date": "2019-09-25"
                }
            ]
        },
        {
            "month_year": "9-2019",
            "events": [
                {
                    "id": 32,
                    "title": "Event 4",
                    "description": "Event 4",
                    "date": "2019-09-04"
                },
                {
                    "id": 29,
                    "title": "Event 1",
                    "description": "Event 1",
                    "date": "2019-09-25"
                }
            ]
        }
    ]
}

it should be like this

{
    "count": 4,
    "next": null,
    "previous": null,
    "results": [
        {
            "month_year": "6-2019",
            "events": [
                {
                    "id": 30,
                    "title": "Event 2",
                    "description": "Event 2",
                    "date": "2019-06-02"
                },
                {
                    "id": 31,
                    "title": "Event 3",
                    "description": "Event 3",
                    "date": "2019-06-04"
                }
            ]
        },
        {
            "month_year": "9-2019",
            "events": [
                {
                    "id": 32,
                    "title": "Event 4",
                    "description": "Event 4",
                    "date": "2019-09-04"
                },
                {
                    "id": 29,
                    "title": "Event 1",
                    "description": "Event 1",
                    "date": "2019-09-25"
                }
            ]
        },

    ]
}

check you data base from django admin maybe you duplicate the data !
there is no error in the code

 
Classic DEV Post from Jan 20

My dev life has just started 😎👩‍💻

Borhan Uddin Tipu profile image