【问题标题】:breaking the django json response打破 django json 响应
【发布时间】:2020-05-18 11:18:06
【问题描述】:

我对代码有以下响应:

{
    "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                
        }
    ]
},

我使用序列化程序编写了以下代码:

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

但是,我希望得到以下答复:

{
    "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                
        }
    ]
},

我想解释一下,广告是以列表形式出现在单个响应中的。我想用相同的名称、start_date、end_date 值打破广告。有可能吗?

更新 1:

之后,我得到的回复之一,

[
    {
        "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"
    }
],

上面的响应算作一个 JSON 响应而不是三个,因为响应是一个列表,而不是三个不同的列表。那么,是否有人可以帮忙?

【问题讨论】:

    标签: python django python-2.7 serialization


    【解决方案1】:

    在序列化器级别,您可以通过覆盖AdsDetailOnScheduler 类中的to_representation 方法来实现(下面的示例)。

    但是因为消费者而改变响应并不是一个好习惯。 API 使用者应根据需要处理 API 响应。如果您可以访问消费者代码,我建议您将其更改为破坏对象关系。

    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
    

    【讨论】:

    • 我必须在我的序列化程序类中添加这个?
    • 是的。这是为了覆盖默认的表示行为
    • 你在运行python2.x吗?如果是,请相应地标记问题。
    • super 已排序!,我实际上收到了 NoneType 的错误。 JFYI , "广告也可以为空
    • 那是因为你是这样写的。如果有广告,则不应返回 None。最好返回一个空列表[]。然后函数签名不会改变。你可以通过返回[AdsDetailSongScheduler(ad).data for ad in Ads.objects.filter(id__in = ad_id)]
    猜你喜欢
    • 2014-01-18
    • 2015-03-30
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多