【问题标题】:Make multiple API calls and update in a loop using Django使用 Django 进行多个 API 调用并循环更新
【发布时间】:2019-03-10 08:43:17
【问题描述】:

我正在尝试进行 API 调用,并且当我从表单使用给定输入请求它时(因此返回一条记录,并对该记录进行 API 调用),我能够使其工作。现在,如果没有提供输入,我想遍历实际表中的所有行,并对任何丢失的数据列进行 API 调用......

但是,当我尝试在同一页面上发出多个请求时,在表单提交时,我无法让 api 调用工作,我收到此错误:

/url 处的 JSONDecodeError 期望值:第 1 行第 1 列(字符 0) 请求方法:POST 请求网址: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..

path('api//', views.API.as_view(), name='a')

我需要在 Django 中进行此 API 调用(因为调用基于返回的内容),因此我不能为此使用 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'])

不能循环工作。我验证了循环确实调用了更新。

【问题讨论】:

  • 那么调用 getAnotherAPICall() 是什么?
  • 用更多代码更新了问题..
  • 想通了这一点,我认为是当 API 没有返回任何错误被抛出时......所以,当没有返回数据时,我可能不得不返回类似于什么的东西预期....但是,多行更新现在在循环中不起作用!

标签: django django-models django-forms django-rest-framework django-request


【解决方案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)

【讨论】:

    猜你喜欢
    • 2022-03-11
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    • 2021-11-16
    • 2014-12-07
    • 1970-01-01
    • 2020-12-26
    • 1970-01-01
    相关资源
    最近更新 更多