Django休息框架 - http post在viewset中调用create()方法两次导致序列化程序错误

时间:2016-03-24 21:12:44

标签: django django-rest-framework

我正在使用django rest框架来创建api端点。我重写了CreateModelMixin类的create函数。当前端发送一个POST请求时,这个create()会被同时调用两次,就像它被并行处理一样!! - 我可以看到这个create function中的所有日志语句打印两次。因此,当序列化程序保存发生时,只有第一个请求对象通过,第二个请求对象导致错误(显然,因为它已经创建)。

我的观点:

class AdGroupViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):

def create(self, request, *args, **kwargs):
    data_copy = request.data.copy()
    print 'the create request data'
    print request.data
    #Request data has params name appended with a'[]'
    #if its an array, hence removing '[]' from the name
    geo_key=''
    if 'geotargeting[]' in data_copy:
        geo_key ='geotargeting[]'
    elif 'geotargeting' in data_copy:
        geo_key='geotargeting'

    if geo_key:
        print 'geotargeting info present in incoming request'
        geos = data_copy.getlist(geo_key)
        del request.data[geo_key]
        print geos
        for geo in geos:            
            try:
                geoObj = GeoTargeting.objects.get(criteria_id=int(geo))
                print  'geo db id: '+str(geoObj.id)
                request.data.update({'geotargeting' : unicode(str(geoObj.id))})
            except Exception as e:
                logger.error("Error in updating GeoTargeting "+str(e))
    try:

        for item in data_copy.getlist('iab_category[]'):
            request.data.update({'iab_category':unicode(item)})


        for item in data_copy.getlist('exchange[]'):
            request.data.update({'exchange':unicode(item)})

        for item in data_copy.getlist('creative[]'):
            request.data.update({'creative':unicode(item)})

        print "targeting iofo "+str(request.data[geo_key])
        print "iab info "+str(request.data['iab_category'])
        print 'exchange info '+str(request.data['exchange'])
        print 'creative info '+str(request.data['creative'])
        del request.data['iab_category[]']
        del request.data['exchange[]']
        del request.data['creative[]']


    except Exception as e:
        logger.error("error is "+str(e))
    try:

        print 'final data'
        print request.data
        serializer = AdGroupCreateSerializer(data=request.data)
        if serializer.is_valid():
            print 'serialzier is correct '
            serializer.save()
            headers = self.get_success_headers(serializer.data)
            print serializer.data
            return Response(data=serializer.data['id'], status=status.HTTP_201_CREATED, headers=headers)


        print "ERROR:"+str(serializer.errors)
        return Response(data=str(serializer.errors),status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    except Exception as e:
        logger.error('create error is '+str(e))
        traceback.print_exc()
        return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)

打印两次的日志语句示例:

the create request data

the create request data

 <QueryDict: {u'creative[]': [u'1785276'], u'cpm_target': [u'0'], u'tactic': [u'1'], u'end_date': [u'2016-03-25T00:00:00-07:00'], u'cpm_bid': [u'2'], u'geotargeting[]': [u'200532'], u'campaign_id': [u'6'], u'start_date': [u'2016-03-15T00:00:00-07:00'], u'ad_type': [u'0'], u'iab_category[]': [u'9'], u'exchange[]': [u'3'], u'bidding_freq': [u'0'], u'freq_cap': [u'2'], u'total_impression_limit': [u'2'], u'adgroup_name': [u'ram staging test4'], u'daily_impression_limit': [u'2']}>

<QueryDict: {u'creative[]': [u'1785276'], u'cpm_target': [u'0'], u'tactic': [u'1'], u'end_date': [u'2016-03-25T00:00:00-07:00'], u'cpm_bid': [u'2'], u'geotargeting[]': [u'200532'], u'campaign_id': [u'6'], u'start_date': [u'2016-03-15T00:00:00-07:00'], u'ad_type': [u'0'], u'iab_category[]': [u'9'], u'exchange[]': [u'3'], u'bidding_freq': [u'0'], u'freq_cap': [u'2'], u'total_impression_limit': [u'2'], u'adgroup_name': [u'ram staging test4'], u'daily_impression_limit': [u'2']}>

request method isPOST

request method isPOST

final data <QueryDict: {u'cpm_target': [u'0'], u'tactic': [u'1'], u'end_date': [u'2016-03-25T00:00:00-07:00'], u'cpm_bid': [u'2'], u'exchange': [u'3'], u'campaign_id': [u'6'], u'start_date': [u'2016-03-15T00:00:00-07:00'], u'ad_type': [u'0'], u'iab_category': [u'9'], u'geotargeting': [u'38824'], u'bidding_freq': [u'0'], u'freq_cap': [u'2'], u'total_impression_limit': [u'2'], u'creative': [u'1785276'], u'adgroup_name': [u'ram staging test4'], u'daily_impression_limit': [u'2']}>

final data <QueryDict: {u'cpm_target': [u'0'], u'tactic': [u'1'], u'end_date': [u'2016-03-25T00:00:00-07:00'], u'cpm_bid': [u'2'], u'exchange': [u'3'], u'campaign_id': [u'6'], u'start_date': [u'2016-03-15T00:00:00-07:00'], u'ad_type': [u'0'], u'iab_category': [u'9'], u'geotargeting': [u'38824'], u'bidding_freq': [u'0'], u'freq_cap': [u'2'], u'total_impression_limit': [u'2'], u'creative': [u'1785276'], u'adgroup_name': [u'ram staging test4'], u'daily_impression_limit': [u'2']}>

serialzier is correct
serialzier is correct
create error is
create error is

版本:     Django rest framework = 3.2.2     Django = 1.6.5     Apache = 2.2.29

奇怪的是,在本地机器上测试没有这个问题。 请求META两次都是相同的。

0 个答案:

没有答案