I am trying to make an API call and am able to get it working when I request it with a given input (so returning one record, and making the API call on that one record) from a form. Now, if the input is not provided I want to loop through all rows in the actual table, and make API calls for any missing data columns...
However, when I try to make multiple requests on the same page, on form submit, I can't get the api call to work, I get this error:
JSONDecodeError at /url
Expecting value: line 1 column 1 (char 0)
Request Method: POST
Request URL: http://localhost:8000/url
Django Version: 2.1.1
Exception Type: JSONDecodeError
Exception Value:
Expecting value: line 1 column 1 (char 0)
Exception Location: C:\Users\AppData\Local\Programs\Python\Python37-32\Lib\json\decoder.py in raw_decode, line 355
Python Executable: C:\Users\.virtualenvs\projects\Scripts\python.exe
UPDATE: This was the API failing, not Django. Leaving the rest of the question in as bulk updates do not work
views to make the API call:
class API(View):
def get(self, request, *args, **kwargs):
url = 'https://ExternalAPI/{param1}'.format(param1=param1)
response = requests.get(url, headers={'x-Key': settings.KEY})
if response.status_code == 404:
return JsonResponse({})
return JsonResponse(response.json()[0])
# Works for 1 row, doesn't work when called within a loop from a form submission....
def getAnotherAPICall(self, request, address):
print('getting data...')
response = requests.get('{}?param={}&id={}'.format(settings.URL, data, settings.ID))
data = response.json()
result = data['Response'][0] # This is based on the API itself....
if response.status_code == 404:
return {}
return result
There is no URL for the custom method..
path('api//', views.API.as_view(), name='a')
I need to make this API call from within Django (as the calls are based on what's returned) so I cannot use Javascript or a frontend approach for this..
class MyView(TemplateView):
def post(self, request):
form = MyForm(request.POST)
formIDInput = form.cleaned_data['formIDInput']
apiData = []
if form.is_valid():
if(formIDInput):
resultQuerySet = MyModel.objects.filter(PrimaryID= str(formIDInput)) # One row, API call works
else
resultQuerySet = MyModel.objects.all() #Multiple rows, API call doesn't work when API call is made
for result in resultQuerySet:
# This step fails:
apiData = API.getAnotherAPICall(self, request, result.column1) # result.column1 is parameter to make the API call...
apiData.append({
'ID': result.PrimaryID,
'Data': apiData
})
MyModel.objects.update(columToUpdate = apiData['field'])
return render(request, 'template.html', {
'form': form,
'results': resultQuerySet
})
UPDATE: So, I figured out the loop runs just fine. The API was failing on the second record, when the loop was going through just fine. However, multiple/bulk updates to set specific columns using the data returned from the API, doesn't work.
MyModel.objects.update(columToUpdate = apiData['field'])
doesn't work in a loop. I verified the loop does call the update.
To anyone else reading this question, note that I'm a Django novice and maybe using some questionable practises. However, everything on the code in the question works fine, as long as you think of a few things:
from django.db import transaction