我正在使用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两次都是相同的。