Timshrok
Timshrok

Reputation: 107

breaking the django json response

I have the following response with the code:

{
    "id": 716,
    "name": "XYZ",
    "start_date": "2019-12-24",
    "end_date": "2020-01-31",        
    "ads": [
        {
            "id": 20228,
            "no_of_times_per_hr": 1,
        },
        {
            "id": 20227,
            "no_of_times_per_hr": 2
        },
        {
            "id": 20229,
            "no_of_times_per_hr": 7                
        }
    ]
},

I have written this using the serializer with the following code:

class AdsDetailOnScheduler(serializers.ModelSerializer):
    ads = serializers.SerializerMethodField()
    class Meta:
      model = AdCampaign
      fields = ('id','name','start_date','end_date', 'ads')

    def get_ads(self, obj):
      adlabels = AdDayLabelMap.objects.filter(ad_campaign__id  = obj['id']).values_list('ad_label', flat = True).distinct()
      ad_id = AdSlot.objects.filter(ad_label__id__in = adlabels).values_list('ads', flat = True)
      if Ads.objects.filter(id__in = ad_id).exists():
        a = []
        for ad in Ads.objects.filter(id__in = ad_id):
            a.append(AdsDetailSongScheduler(ad).data)
        return a
      else:
        return None  

class AdsDetailSongScheduler(serializers.ModelSerializer):  
    no_of_times_per_hr = serializers.SerializerMethodField()
    after_n_songs = serializers.SerializerMethodField()
    specific_time = serializers.SerializerMethodField()
    class Meta:
      model = Ads
      fields = ('id','no_of_times_per_hr')

    def get_no_of_times_per_hr(self, obj):          
      if obj.no_of_times_per_hr:
         return obj.no_of_times_per_hr
      else:
         return None

However, I would want the response below:

{
    "id": 716,
    "name": "XYZ",
    "start_date": "2019-12-24",
    "end_date": "2020-01-31",        
    "ads": [
        {
            "id": 20228,
            "no_of_times_per_hr": 1,
        },
    ]
},



{
    "id": 716,
    "name": "XYZ",
    "start_date": "2019-12-24",
    "end_date": "2020-01-31",        
    "ads": [
        {
            "id": 20227,
            "no_of_times_per_hr": 2
        },
    ]
},



{
    "id": 716,
    "name": "XYZ",
    "start_date": "2019-12-24",
    "end_date": "2020-01-31",        
    "ads": [
        {
            "id": 20229,
            "no_of_times_per_hr": 7                
        }
    ]
},

I would like to explain that the ads are coming as a list in a single response. I wanted to break the ads with the same values of name, start_date,end_date. Is it possible to do so?

Update 1:

After, one of the responses I get,

[
    {
        "end_date": "2020-01-31",
        "id": 76,
        "ads": [
            {
                "id": 208,                    
                "no_of_times_per_hr": 1
            }
        ],
        "name": "XYZ",
        "start_date": "2019-12-24"
    },
    {
        "end_date": "2020-01-31",
        "id": 76,
        "ads": [
            {
                "id": 207,                
                "no_of_times_per_hr": 2
            }
        ],
        "name": "XYZ",            
        "start_date": "2019-12-24"
    },
    {
        "end_date": "2020-01-31",
        "id": 76,
        "ads": [
            {
                "id": 209,                    
                "no_of_times_per_hr": 7
            }
        ],
        "name": "XYZ",
        "start_date": "2019-12-24"
    }
],

The response above is counted as one JSON response and not three, as the response is one single list and not three different lists. So, if anyone could help out for this please?

Upvotes: 0

Views: 45

Answers (1)

Shiplu Mokaddim
Shiplu Mokaddim

Reputation: 57650

On the Serializer level, you can do it by overriding to_representation method in AdsDetailOnScheduler class (example below).

But it's not good practice to change the response because of the consumer. The API consumer should process API responses according to their need. If you have access to consumer code, I'd suggest changing that as breaks the object relation.

def to_representation(self, instance):
    response_dict = super().to_representation(instance)
    ads = response_dict.pop('ads', [])
    output_list = []
    for ad in ads:
        data = {}
        data.update(response_dict)
        data['ads'] = [ad]
        output_list.append(data)
    return output_list

Upvotes: 1

Related Questions