Делать несколько вызовов API и обновлять в цикле, используя Django

Я пытаюсь сделать вызов API и могу заставить его работать, когда я запрашиваю его с заданным входом (возвращая одну запись и делая вызов API для этой одной записи) из формы. Теперь, если ввод не предоставлен, я хочу перебрать все строки в фактической таблице и сделать вызовы API для любых отсутствующих столбцов данных...

Однако, когда я пытаюсь сделать несколько запросов на одной странице, при отправке формы, я не могу заставить вызов API работать, я получаю эту ошибку:

JSONDecodeError at / url Ожидаемое значение: строка 1, столбец 1 (символ 0) Метод запроса: POST URL-адрес запроса: http://localhost:8000/url Django Версия: 2.1.1 Тип исключения: JSONDecodeError Значение исключения:
Ожидаемое значение: строка 1, столбец 1 (символ 0) Местоположение исключения: C:\Users\AppData\Local\Programs\Python\Python37-32\Lib\json\decoder.py в raw_decode, строка 355 Исполняемый файл Python: C:\Users\.virtualenvs\ Projects\Scripts\python.exe

ОБНОВЛЕНИЕ: Это был сбой API, а не Django. Оставляя остальную часть вопроса в виде массовых обновлений, не работают

представления для вызова API:

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

Там нет URL для пользовательского метода..

путь ('api//', views.API.as_view(), name='a')

Мне нужно сделать этот вызов API из Django (так как вызовы основаны на том, что возвращено), поэтому я не могу использовать для этого Javascript или подход с использованием внешнего интерфейса.

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
        })

ОБНОВЛЕНИЕ: Итак, я понял, что цикл работает нормально. Сбой API на второй записи, когда цикл проходил нормально. Однако многократное / массовое обновление для установки определенных столбцов с использованием данных, возвращаемых из API, не работает.

MyModel.objects.update(columToUpdate = apiData['field'])

не работает в цикле. Я подтвердил, что цикл вызывает обновление.

1 ответ

Решение

Всем, кто читает этот вопрос, обратите внимание, что я новичок в Django и, возможно, использую некоторые сомнительные практики. Тем не менее, все в коде в вопросе работает нормально, если вы думаете о нескольких вещах:

  • Подумайте о крайних случаях, например, если API ничего не возвращает. Вернуть '' или None или что-то еще, а затем проверить, есть ли что-то возвращенное перед обработкой полей данных. Добавьте раздел исключений try, чтобы, если API действительно выдает ошибку, вы могли вернуть что-то обратно.
  • Django.update не работает в цикле с разными значениями данных для одного и того же столбца, поэтому сделайте это вместо этого:

из транзакции импорта django.db

@staticmethod

def updateBulk(id, newValue):
    rows = MyModel.objects.filter(id=id)

    transaction.set_autocommit(False)
    for row in rows:
            row.column1 = newValue

        row.save()
    transaction.commit()
    transaction.set_autocommit(True)
Другие вопросы по тегам